• 2

    posted a message on Hey guys I am 14 year old and I want to learn coding to make mods and maybe plugins to
    advice: don't use any mod-creation tool if you want to get serious. MCreator is fine if you just want to have fun modding blocks/items, but if you want to go beyond and really want to make cool stuff, get a java book (My all time favorite is Head First Java, and no I'm not paid for the ad). It is not the fastest way nor easiest, but it will defintely pay off soon. You can't make good stuff without knowing the language. There is no way around. Once you get the concepts of Object Oriented Programming, you'll automatically understand the tutorials online, and you can even find mistakes in them.
    Posted in: Modification Development
  • 0

    posted a message on Modding Tutorials for an Experienced Programmer?
    I guess the hardest part is to wrap your head around the messy implementations that minecraft has. Most experienced people worked a lot with industrial de facto grade code, while minecraft code is on the other end of the scale. I think the first lesson should be shutting up and stop wondering why minecraft needs to implement something like that...

    And thanks to CosmicDan for the link. I really didn't realize that some great tutorials exist!
    Posted in: Modification Development
  • 0

    posted a message on 1.7.10 tutorials past "make basic block/tool/item"?
    Those tutorials don't exist for a reason. Anything beyond simple block/item/texture is flexible enough to be implemented in a thousand different ways. Forge's API covers only part of things people want to do, so if you don't want oreDictionary or fluid, you are left with pure vanilla minecraft code. Tutorials at this point won't help more than reading the source code documentation, which is pretty much the case from what I saw in your thread. That code snippet should go to onBlockActivated method in the Block class. This method is clearly documented as the method handling right-clicks.

    I understand the frustration of looking at 100+ source files trying to find the one you need. Documentations are for references, not teaching after all. Unfortunately, Forge's community tend to stay away from telling people to follow a certain track. Instead, they encourage people to try different ways (as you can see from the abundance of hooks rather than APIs). I don't have much appreciation towards java, so I can't make good java tutorials. I've posted several scala tutorials as it is the main language I use. I guess people still have their main focus on java so the tutorials are not popular at all. If you are interested in learning scala (I do encourage new programmers learn scala instead of java), please check them out. Your interest will become the driving force for me to spit out better written tutorials. Cheers!
    Posted in: Modification Development
  • 1

    posted a message on [1.8] I am disappointed.
    Quote from echonite»

    They only had about 6 months of work days split between 3different games, and they managed to rewrite most of the game's core workings. Not to mention they are all hired on freelancers. I don't think many of them were actually professional programmers before being hired on.

    Well then that explains a lot. If 5 freelancers have to split attention among 3 different projects, then they are not going to deliver well on this million dollar game. Lets hope microsoft can put more man power into this project.
    Posted in: Recent Updates and Snapshots
  • 1

    posted a message on [1.8] I am disappointed.
    Features added in 1.8 are fine. The game is actually maturing in a good way. However, although I understand that it takes time to refine the code base, just looking at 1.8's code doesn't impress me. At least it doesn't look like a whole year's work. They are paid full time professionals, and to be honest, they were doing a subpar job for the past few releases. Some heated hatred is truly irritating, but unfortunately I don't feel the urge to argue for them this time :(
    Posted in: Recent Updates and Snapshots
  • 0

    posted a message on Streams - Real Flowing Rivers
    God finally some great rivers! Can't wait for the release!
    Posted in: WIP Mods
  • 0

    posted a message on [1.7.10]Minecraft modding tutorial 1 --- Understanding Forge Gradle
    Quote from WhysAlives»
    With regards to the first "maven{}", I've seen the "name" property written as both "forge" and "forgeFS". Is there a difference?

    Not really. When I wrote this tut the "forge" version didn't work, so I used "forgeFS". I guess they pulled it down for maintenance. When I update my github repository, it worked again. So I guess (just guessing), the forge repo is the main one, while forgeFS acts as a backup.
    Posted in: Mapping and Modding Tutorials
  • 0

    posted a message on [1.7.10]Minecraft modding tutorial 3 --- Scala Traits in action, having fun making a block!
    Tutorial continues to the second post as it gets really long. Finishing the OP, one can already make a block, so I think that's a good breaking point.


    The "two object make two block" outcome is consistent with our observation before: GameRegistry registers the object, not the class. You can specify the textures too. Just add a parameter in the constructor that's "tex: String", and call setBlockTextureName(tex) in the constructor. Now you defined only one class, but can have as many blocks ingame as you want each with different names and textures. Just instantiate different objects with different parameters.
    "But wait a second," you say. "I can see the benefit, but it's all because names and textures are data. What if we want different behaviors? You can't pass a function definition into the constructor!"
    Scala has you covered. There are a lot of ways you can do that actually! Today, we are going to talk about a way that's not functional, introducing scala traits.
    traits:
    For java programmers, think traits as interfaces with concrete implementations. Java 8 actually has that already. For OOP enthusiasts, you probably already know what's bad about multiple inheritance, and trait is a lightweight class that doesn't have the "diamond of death" problem. For non-programmers, think traits as usb sticks. You can plug usb sticks into a computer to add some functions to the computer. Same with traits, you can plug traits into classes so the class will have more functions. In scala, you add a trait also by the keyword "extends". If you also inherit from a superclass or has more than one trait, use the keyword "with". For example, "class A extends ClassB with Trait1 with Trait2 with ..." , or "class A extends Trait1 with Trait 2 with ...".

    The definition of a scala trait is very humble. However, you can do much more than it looks like because two important features we are going to use here: contruction time mix-in and layered traits.
    Let's first start by looking at the problem. Let's add some more sugar to our BaseBlock class by overriding the onBlockActivated method inherited from Block (on topics about overriding, overloading and function signatures, go check wikipedia).
    code:

      override def onBlockActivated(world: World, x: Int, y: Int, z: Int,
    player: EntityPlayer, meta: Int,
    hitX: Float, hitY: Float, hitZ: Float) = {
    world.spawnEntityInWorld(new EntityItem(world, x+0.5, y+1.0, z+0.5, new ItemStack(Items.diamond)))
    true
    }


    The code above basically means dropping one diamond each time you right click on the block. Nice cheating block to make you rich fast isn't it? However, the line "world.spawnEntityInWorld" is hard coded. You can't pass in a parameter to the method "onBlockActivated" to set which item you want to drop, because the signature cannot be modified when overriding a method. Well, you can passing a parameter in the constructor, and store it as a field in the class, and then access it from within "onBlockActivated". However, that way, you can only customize to a very limited extent. What if you want the block to also play a particle effect or a sound file? Now you miss the old "one block one class" way of doing things. Fear not, using the scala traits' nice features can make your life easier! Follow me closely as the next part will be a little intense.
    We need a functionality to put the code inside "onBlockActivated" somewhere else so that "somewhere else" could change freely. If you are smart enough, you already have the answer: put it inside another method so we have total control of the signature and behavior ("delegation" is the word you need to google). Let's do that:

      override def onBlockActivated(world: World, x: Int, y: Int, z: Int,
    player: EntityPlayer, meta: Int,
    hitX: Float, hitY: Float, hitZ: Float) = {
    executeRightClick(world, x, y, z)
    }


    now you need to find a place to define the executeRightClick method. Scala trait finally comes into play:

    trait RClickable {
    def executeRightClick(world: World, x: Int, y: Int, z: Int) :Boolean = {true}
    }



    No surprise that the trait keyword defines a trait. we just return true here without doing anything useful. mix-in the trait into our BaseBlock definition:
    class BaseBlock(nam: String, mat: Material) extends Block(mat) with RClickable

    and the above code compiles. Enter the game, right click on the block, it doesn't do anything. Now we need to add concrete traits that actually do something. Make a new trait named "DiamondClicker", and extend the base trait "RClickable", then we override "executeRightClick" to make it actually do something:

    trait DiamondClicker extends RClickable {
    override def executeRightClick(world: World, x: Int, y: Int, z: Int): Boolean = {
    world.spawnEntityInWorld(new EntityItem(world, x+0.5, y+1.0, z+0.5, new ItemStack(Items.diamond)))
    super.executeRightClick(world, x, y, z)
    }
    }



    Java programmers probably get very confused here. Why do I call "super.executeRightClick"? Doesn't that method just return true and does nothing else? Hold your breath, as this concept of layered trait will be introduced later. We now go to construction time mix-in first :) .

    If you don't mix-in DiamondClicker anywhere, you will not get a diamond no matter how hard you right-click your blocks. From what we talked before, one's instinct is to mix-in at the definition time. so we make something like "class BaseBlock(nam: String, mat: Material) extends Block(mat) with DiamondClicker".

    However, this way, all our objects instantiated from BaseBlock will drop diamonds when right-clicked! If you don't want diamond spamming, this is not good! Scala traits can actually be mixed-in at construction time! How neat is that! so, we leave our BaseBlock definition as-is, and mix-in at construction time. In your preInit method, change the code like this:

    @Mod.EventHandler
    def preInit(e: FMLPreInitializationEvent) {
    GameRegistry.register(new BaseBlock("blockA", Material.rock) with DiamondClicker, "blockA")
    GameRegistry.register(new BaseBlock("blockB", Material.rock), "blockB")
    }



    run your game, and right-click on blockA, you will get diamonds! Then right-click on blockB, nothing! Are your blood boiling because of excitement? Me too. This neat feature allows you to write a lot less code than that of java, and at the same time be very flexible! Let's push the possibility a little bit further. Now, instead of just spamming diamonds, you want to spam fireworks too. From previous experience, you write a ParticleClicker trait instinctively:

    trait ParticleClicker extends RClickable {
    override def executeRightClick(world: World, x: Int, y: Int, z: Int): Boolean = {
    world.spawnParticle("fireworksSpark", x+0.5, y, z+0.5, 0.0, 1.0, 0.0)
    super.executeRightClick(world, x, y, z)
    }
    }


    Now you mix-in it to blockB: "GameRegistry.register(new BaseBlock("blockB", Material.rock) with ParticleClicker, "blockB")". Now you have a block that shoot fireworks when right-clicked! However, your imagination never stops, and you want a block that spawns both diamonds and fireworks, how do you do that? This is where our "super.executeRightClick" line comes into play. Usually, if you want to combine behaviors, you have to write a new trait that has two lines of code, both "world.spawnEntityInWorld" and "world.spawnParticle". Scala releases you from that pain. Add this line to your preInit method:

    @Mod.EventHandler
    def preInit(e: FMLPreInitializationEvent) {
    GameRegistry.register(new BaseBlock("blockA", Material.rock) with DiamondClicker, "blockA")
    GameRegistry.register(new BaseBlock("blockB", Material.rock) with ParticleClicker, "blockB")
    GameRegistry.register(new BaseBlock("blockC", Material.rock) with ParticleClicker with DiamondClicker, "blockC")
    }



    and Tada! you get yourself a new blockC that spams diamonds AND plays fireworks without writing any new class definitions! This is the power of layered trait. The call to "super.executeRightClick" doesn't call the base trait "RClickable", but calls the trait before it! In our blockC, when right clicked, we first call DiamondClicker's executeRightClick, and then call ParticleClicker's executeRightClick. Wow! How smart is scala! This way, we can chain the calls where order matters, and mix&match to create brand new objects on the fly. If you want to make 100 blocks each doing different stuff using the old way, you'll have to write 100 classes. With scala, you can write 10 traits + one base class, and yield 1024 different combinations in total!

    End words:

    scala is powerful and fun. Hope you learned something and be fascinated by the language after completing this tutorial!
    Posted in: Mapping and Modding Tutorials
  • 0

    posted a message on [1.7.10]Minecraft modding tutorial 3 --- Scala Traits in action, having fun making a block!
    Update: I created a git repository on GitHub for this series. Check it out! The Repo

    The last tutorial was quite intense to read and boring because of the terms. This one, I'll start writing a block right away, but with some nice scalatic taste in it! Note this is also going to be very long since I introduce much more than making a simple block. Read to the end, I guarantee that you'll have fun!

    Tutorials teaching you how to make blocks are everywhere. OrangeTutorial has a quite good one. However, many of them suffer from being too vague and overlook some potential problems. It is a compromise to the fact that many readers have no programming knowledge at all. Since people interested in reading this tutorial may already dragged themselves through the last one, I'll go ahead and assume you understand the basic idea of OOP like classes and instances. I didn't get into one of the most important OOP concept of inheritance, so this is the place to introduce.

    The process of making a block is distilled to the following steps: 1). Make a subclass of Block class. 2). do something in the constructor to setup the block to have correct names, tectures, and appear in a creative tab. 3). new an instance of the block and store it somewhere. 4). use GameRegistry to register the newed instance.

    explanation of inheritance
    What's a subclass? OOP is all about designing, so you write a lot of blueprints to describe the objects you are gonna make. It is a very labor intensive task, so people came up with inheritance. Inheritance basically is an automatic copy-paste, when a class A inherits from another class B, we call A a subclass of B. By inheriting from B, A automatically gets everything that B has. Be it variables defined in B, and all the methods too. the extends keyword in both java and scala means inheritance. Go back and check OrangTutorial's block page. the OrangeBlock extends Block from minecraft, so it is a subclass of the Block class (Block is the superclass of OrangeBlock). Because subclasses gets the thing from the superclass for free, so that OrangBlock class gets the "super" constructor, "setCreativeTab", "setBlockName" and "setBlockTextureName" automatically.


    I don't know if anybody noticed or not, but every time you want a new block, you have to create a separate subclass of Block. Much worse, you have to call setCreativeTab and all those methods again. that's a lot of typing! There is yet another pitfall to this approach. What if Mojang had a meeting and decided that they want to call "setCreativeTab" as "setAwesomeTab" instead? If you have 100 blocks, you'll have to update 100 files when you update! This might not be a problem for user of IDEs with the refactoring functionality, but if the parameters of "setCreativeTab" changed from a CreativeTab to CreativeTab and the block? You don't just update the name, you have to update how it is used, and eclipse's refactoring definitely will not help!

    If you reason thoroughly, GameRegistry registers the object, not the class. So, if you want a different block, why not create another instance? Instead of having 100 classes, why can't we have only one class but 100 objects? If you feel "Aha!", then welcome to the next level of programming :) .

    The main code for this tutorial. Modified from OrangeTutorial. I only show main points, so things like package and import will be ignored. I think most people uses eclipse, so when you see redlines, press "ctrl+shift+o", and it will automatically handle import for you.

    class BaseBlock(nam: String, mat: Material) extends Block(mat){
    setBlockName(nam)
    setCreativeTab(CreativeTabs.tabBlock)
    }

    Very short isn't it? You can already appreciate scala!


    And in your main mod file's preInit method:

      @Mod.EventHandler
    def preInit(e: FMLPreInitializationEvent) {
    GameRegistry.registerBlock(new BaseBlock("blockA", Material.rock), "blockA")
    GameRegistry.registerBlock(new BaseBlock("blockB", Material.rock), "blockB")
    }



    And "gradle build", "gradle runClient". Create a creative world, and Tada! you have two blocks in the blocks creative tab, while you only have one class for the block!

    explanation:
    As you have guessed, the lines in preInit did the trick. You initialized two different objects by calling "new BaseBlock" twice. the "blockA" and Material.rock passed in are parameters for the constructor. As you can see, in the BaseBlock definition, I tell scala explicitly that I wanted two parameters for the constructor. "nam" is a String type, corresponding to "blockA"; mat is of type Material, corresponding to Material.rock. The scala syntax for constructor is very different than java. in java, you have a method like definition that has the same name as the class itself, and that's the constructor (in java, our constructor would be "public BaseBlock(String nam, Material mat)"). In scala, the constructor is combined with the class definition itself, as our example shows "class BaseBlock(nam: String, mat: Material)". In java, if you want to pass a parameter to the Block class, you have to do it in the constructor and call super(mat). In scala, you just put it in the definition also, as you can see in "extends Block(mat)".
    The tutorial continues to post #2.
    Posted in: Mapping and Modding Tutorials
  • 2

    posted a message on [1.7.10]Minecraft modding tutorial 2 --- Setting up Scala Mods
    Update: I created a git repository on GitHub for this series. Check it out! The Repo

    Starting from this one, I'll write about making mods in scala. Rather than getting specific jobs done like adding biomes, making skeleton cry, or "how to add a bow that only damage pigs", I'm only going to go as far as making blocks, items and tileEntities (the big three). I'm not a pro in writing all kinds of minecraft stuff, and that kind of tutorial is so sufficient that I'll look like an idiot compared to others. However, I see a need of learning scala because of the ForgeMultiPart library, and a lack of tutorial on scala. I then decided to fill in the blank. I will look into ForgeMultiPart library as I move on, and hopefully can provide some concrete examples in using it :) .

    As a side note, I noticed many people modding have actually very limited knowledge of the tools they are using. They try to get to creating working blocks and items before they even understand what the line new ClassA(arg1, arg2) means, and the differences between int and Integer. I'm not going to lecture about java and OOP, but I do suggest everyone to learn the language and programming concepts before they continue modding. Otherwise, you'll leave yourself a maintenance hell afterwards if you have no idea why you made those mistakes. In that sense, I recommend people who wants to get serious really go invest on an actual programming book. The one I recommend on learning java and OOP is the Head First Java book.

    Back to topic. The general impression that scala is hard came from the fact that there is no scala books for absolute beginners. Afterall, functional programming isn't the easiest thing to grasp. However, scala's OOP aspect is no different than java. One can actually copy java code and get rid of public/static, semicolons and return, and it becomes perfectly valid scala code (well not actually, you have to put types after variable names, and use val/var to declare them). One can treat scala as a disguised java in most places. The best advantage of scala is its expressiveness. Even though we have the help of powerful IDEs like eclipse, we still have to type a lot in java when writing loops and declaring classes. Let's admit it, it is BORING! why not just start learning a fun language if you don't know any language before? Forge provides full scala support, so let's utilize that privilege and dive into minecraft with the fun scala!

    Tutorial 2 is on setting up basic main mod file with forge. If you don't know how to setup a forge environment, there are tons of tutorial out there, and of course, tutorial 1 written by me. However, I assume you follow the track of my tutorial(installing a gradle environment), and have basic knowledge of how to create new files both by hand and in eclipse.

    Steps:

    1. We need to modify our build.gradle script to include support for scala. Gradle has built in support, so we just need to add the line:
    apply plugin: 'scala'
    before the line:
    apply plugin: 'forge'
    final result:
     apply plugin: 'scala'
    apply plugin: 'forge'
    and that's it. Note that you have to put 'scala' before 'forge', because 'scala' is dependent on 'java', which 'forge' includes implicitly. Thus, the plugin dependency goes in order, where if A depends on B, we put A then B. If you are using eclipse and forge's source distribution, make sure you add the apply plugin: 'scala' line first, and then run "gradlew.bat setupDecompWorkspace", then "gradlew.bat eclipse".

    2. Here we are: the main class file. Put it in the src/main/scala folder, and name whatever you want. For best practice, if your package says com.example.examplemod, put the file into src/main/scala/com/example/examplemod folder.

    If you are using eclipse, you need to install the scala IDE plugin. Go to Help->eclipse marketplace->search and type in "scala", you'll see it at the top. Choose the latest version and restart eclipse, you'll be able to write scala in eclipse now! Open the forge project as usual, create a folder under src/main called "scala", and create a class as you would in java development. put the following code in.

    Let's see if the formatting works or not:


    package crn.mods

    import cpw.mods.fml.common.Mod
    import cpw.mods.fml.common.event.FMLInitializationEvent
    import cpw.mods.fml.common.event.FMLPostInitializationEvent
    import cpw.mods.fml.common.event.FMLPreInitializationEvent
    import org.apache.logging.log4j.LogManager

    @Mod(modid = "MineScala", name = "Mine Scala", version = "SNAPSHOT", modLanguage="scala")
    object ExampleMod{
    val logger = LogManager.getLogger("MineScala")

    @Mod.EventHandler
    def preInit(e: FMLPreInitializationEvent) {
    logger.info("OMG I'm in the preInit method! Hooray!")
    }

    @Mod.EventHandler
    def init(e: FMLInitializationEvent) {
    logger.info("OMG I'm in the init method! Hooray!")
    }

    @Mod.EventHandler
    def postInit(e: FMLPostInitializationEvent) {
    logger.info("OMG I'm in the postInit method! Hooray!")
    }
    }



    explanations for step 2, where the juices are, but lengthy and technical:

    1). same as java, scala organizes code into packages. This is to provide control to scope. You can think of scope as rooms, and the package line as addresses. Everyone in the same room can easily get to each other, but to get to someone in another room, you need that room's address first. This automatically leads to the explanation of import. If B is in room earth.africa.sahara.nowhere, you have to go there every time you want to find B. "import earth.africa.sahara.nowhere.B" acts as a magical door that opens a worm hole to B, and the next time you want to find B, B is easily accessed in place. import keyword brings the name in scope, so you can access it as if it is in the same room from the beginning.



    2). @ keyword gives us something called annotations. It's a fancy word for "nametags". By annotate our "TestMod" with fml's "Mod" annotation, we tell fml that this class is our mod class, all the initialization event will be sent here. "modid" is a unique string for identifying your mod. "name" is a human legible name for your own reference. "version" is self explanatory. Notice the modLanguage='scala' part, this is where scala mods differ from java mods. Usually, FML instantializes your class, and put the instance into the @instance field. If you are declaring this class to be an scala object, it is already done by scala, so FML doesn't need to repeat. You just tell FML not to instantialize by adding the line "modLanguage='scala'". The same is true with all the "@Mod.EventHandler" annotations. We just tell fml to call these methods when that event occurs. def keyword defines methods. It is no more than a block of code that does something. In this example, preInit, init, and postInit are all methods that handles the specific event in their parameters. parameters are things to pass to a method. If a method returns nothing as void in java(in scala, they actuall returns (), a type of Unit), it is called a procedure. If the method returns some value, it is called a function. In this case, all three of our methods are procedures. This distinction is very important in functional programming!



    3). FML requires that the main mod to include the three event handler methods. You put all your mod related code inside the curly brackets("{" and "}"). According to FML, you want to initialize and register blocks, items, entities and GUIs in the preInit part, do networking registries in the Init part, and do interactions with other mods in the postInit part.




    4). scala object and scala class. a scala class is the same as a java's. However, scala doesn't have the static keyword, so they add another type "object", which is a singleton (only has one instance). If you want a place to store your global constants like modid, mod name, you can use an object. In our main mod's case, FML asks mod makers to implement their main mod class as a singleton, and scala object is a natural fit. If you don't know OOP, you can think class as a blueprint, and an instance as the realized object created from that blueprint, like the relationship between architecture blueprint and the actual building.



    5). the val keyword. It is used to declare a name as a constant, and assign a value to it. For example, our logger is a constant with a value returned from LogManager.getLogger method. The nature that it is a constant means you cannot assign another value to it later on. so if you say "logger = LogManager.getLogger("SomethingElse")" later, the code will not compile. This is very different from java, where java declares all names as variables by default. If you want to make something constant in java, you need to add the keyword final. Scala can also declare a variable, just replace val with var. However, that is not recommended. Using constants instead of variables is a key practice leading to good functional programming. It is so important that scala has made the val keyword dedicating to declare constants. If you reason thoroughly, you can see there is no need to change the value of logger later on, so a constant is more logical than a variable.



    3. Remember that forge's source distribution includes a default mcmod.info file in the "src/main/resources" folder? Let's modify the modid field to whatever you put in your @Mod's modid field. For this tutorial, put in "YourID". This way, forge knows that this mcmod.info file correspond to your mod. Editing of other fields are explained thoroughly in other mods. I'm not gonna reiterate here.

    4. This code compiles with "gradle build". After calling "gradle runClient", you can see your mod in the mod menu. If you use eclipse, simply click on run. eclipse will build the project first and run it. Also, check out the log file in your run folder, you should see the lines "OMG I'm in preInit/init/postInit methods! Hooray!" in it.

    This tutorial did nothing except adding your mod to the mod menu list, and spam the log file with overly exciting comments. However, the explanation of the syntax is needed for your further understanding of scala. I'm not being thorough here and omitted a lot of details for the sake of simplicity.
    Posted in: Mapping and Modding Tutorials
  • 1

    posted a message on [1.7.10]Minecraft modding tutorial 1 --- Understanding Forge Gradle
    Thank you for the interest and formatted code :) I'm glad that I helped. The OP is replaced with your formatted text.

    I was about to write a follow up tutorial about the source directory setup and the build-by-convention strategy used by gradle's java plugin, but no one replied for the past few days, so I slacked off a little bit...

    Now that you asked, I'll just reply here, and probably update the OP (just probably...).
    Also, couple of questions. You don't use them in your example, but would you be willing to provide a brief explanation of using "sourceSets{}" right after applying the plugin...
    sourceSets {
    main {
    java { srcDirs = ["$projectDir/java"] }
    resources { srcDirs = ["$projectDir/resources"] }
    }
    }

    In short, the plugin "forge" is dependent on gradle's internal plugin "java". the "java" plugin uses a build-by-convention strategy. It means that instead of having the user to say where the source code is every time, gradle just use default folder names. Thus, without the block "sourceSets", gradle looks for java source files in "main/java" folder, and the resource files in "main/resources" folder. With the code you supplied above, gradle looks for folders named "java" instead of "main/java", and "resources" instead of "main/resources". The "$projectDir" is just an internal variable that points to the root directory where your "build.gradle" file resides.
    ...and the "assetsDir" inside "minecraft{}"...
    minecraft {
    version = "1.7.10-10.13.2.1236"
    assetDir = "eclipse/assets"
    }

    the "assetDir" name is used to specify where to store the assets (textures, sounds, etc). Remember you can click "run" in eclipse to boot up a minecraft game? the "runDir" I talked above says where you want to put the runtime files (configs, logs, saves, etc.). However, the assets are put into different directories than the other files. If you don't put this line to specify where you want the assets to be downloaded, gradle will automatically download them into the default location (which is the ".gradle" folder in your "C:/Users/your_user_name" folder).
    ...as well as the following properties that can be placed at the end of the file?
    group            = ""
    archivesBaseName = ""
    version = ""

    Try to run "gradle build" without putting anything in those lines. After the build finishes, go into "build/libs" directory from your project's root. You'll find a jar file there that's named something weird like ".jar". That's the packaged mod file ready for distribution. Probably you figure it out by now: the archivesBaseName field and version field determines this jar file's filename. The built jar file will be named as "archivesBaseName-version.jar". The last field, group, has no impact on the build process. It identifies your development team by a name following apache maven's tradition. It only shows its impact if you want to setup an apache maven repository so that other people could download your jar file freely. The maven repository system is something I never bother to dive into. If you are interested, there are tons of things you can read. Just type "maven" into google and have fun :)
    Posted in: Mapping and Modding Tutorials
  • 0

    posted a message on Throwable Bricks Mod - New Overhaul! And... Brick Cannons? Sweet!
    I don't think the download links in OP work. Could you fix them? (especially the 1.7.10 one). Thanks!
    Posted in: Minecraft Mods
  • 0

    posted a message on Eloraam is working on Redpower 3!
    It seems like she's making a new game, not an updated mod. Sorry for the OP but you probably won't get RP3 in minecraft...

    I usually like a minimalistic design, that's why I still keep the original red logic banner in my posts. since RP2 she kinda failed me. It just adds too much content and shifted game play too much. However, a new game is a completely different story, and RP is quite promising.
    Posted in: Mods Discussion
  • 1

    posted a message on [1.7.10]Minecraft modding tutorial 1 --- Understanding Forge Gradle
    Update: I created a git repository on GitHub for this series. Check it out! The Repo

    Many tutorials out there doesn't really tell you what the concepts in modding are. Instead, they just tell you very specific steps without explaining. I have learned a lot from the community, so now I feel it is time to give back by writing a concise and yet easy tutorial on Forge Gradle modding. If you are the type that doesn't care and just want to get things done without knowing why, then this tutorial is not for you.

    Let's start from a little introduction to Gradle. It is an automatic build tool and nothing else. Instead of downloading libraries and invoking java compiler manually, Gradle does these for you. All you have to do is write a build script (the famous build.gradle file), and call “gradle” in the command line to run that script, and that's it.

    Forge Gradle is nothing but a Gradle plugin. By putting the well known line:
    apply plugin: 'forge'
    into the build.gradle file, you tell Gradle that you are using Forge's preset stuff to build your project. Those presets are well written by the Forge team so that you don't have to know any details but still can develop a mod. Also, the plugin is “in the cloud”, which means all the files that you need will be downloaded only when you need them. Forge source distribution is only 170KB nowadays. You can now see where all those source codes went! The presets include the setupDecompWorkspace, cleanCache, runClient, build etc. That's why you see all the tutorials out there tell you to put “gradlew.bat setupDecompWorkspace” into the command line when you start to mod.

    What's gradlew.bat then? The official Forge source code is distributed with a wrapper, and that's the gradlew.bat file (“w” for wrapper) and the folder "gradle". Why is this necessary? Because by using the wrapper, one doesn't need to download and setup a full Gradle environment (installing Gradle manually involves setting up environment variables like GRADLE_HOME on your system, which most people doesn't like).


    After all the waste of time reading the above explanation, one will ask that why those are important. If you are smart enough, you may already guessed the answer: because in the end, you don't need to download the Forge source code to start a new mod! Why? Because the forge source is fetched by Gradle automatically, given that you setup the build.gradle script right! In order to understand how it works, in this tutorial, we are going to setup a Forge development environment without downloading anything but the Gradle distribution.


    The Steps:
    Step1: download Gradle from their official site: http://www.gradle.org. Choose binary only. You don't need the source code.



    Step2: extract the zip file to a folder. For example: c:/gradle.



    Step3: System specific, as most guys are on Windows, I'll use Windows as example. Right click on Computer → Properties → Advanced system settings → Advanced tab → Environment Variables button. In the popped up dialog of Environment Variables, click “new” under the user variable section (not the system section! Usually it is a bad idea to modify the system variables!). Enter GRADLE_HOME as the variable name, and put your gradle directory as the value. By gradle directory, I mean the directory that you extracted Gradle into, and the directory should directly contain bin, lib and media folders. For example, if you have c:/gradle/bin, then the gradle directory is c:/gradle.



    Step4: Find path under the user variable section, click “edit”, add a semicolon if there is not one, and add “%GRADLE_HOME%\bin” to the end (without quotation marks). Click OK until all dialogs are gone.



    Step5: now you are done setting up a Gradle environment manually. Next, create an empty folder, and create an empty file named “build.gradle”. Add the following lines to it:


    /**
    * Documentation:
    * http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2290037-1-7-10-minecraft-modding-tutorial-1-understanding
    formatted by WhysAlives.
    */
    buildscript {

    repositories {
    mavenCentral()
    maven {
    name = "forge"
    url = "http://files.minecraftforge.net/maven"
    }
    maven {
    name = "sonatype"
    url = "https://oss.sonatype.org/content/repositories/snapshots/"
    }
    }
    dependencies {
    classpath "net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT"
    }
    }
    apply plugin: 'forge'

    minecraft {
    version = "1.7.10-10.13.2.1258"
    runDir = "eclipse"
    }




    Let's explain a little bit:

    apply plugin: 'forge' tells Gradle to use forge's presets. However, Gradle doesn't know where Forge is located. Thus the block “buildscript” is put before it. Code inside buildscript tells Gradle where to look for things. The "repositories" block locates the a repository online at the URL specified. mavenCentral points to apache's central server to look for repos, and the other "maven" block tells gradle that this is a maven repo at "http://files.minecraftforge.net/maven". "dependencies" block describes the library to look for. In this case, it tells gradle to include forgeGradle into the classpath.

    Also notice the block "minecraft". Forge need to know which version to use, so this is where you tell it. Ignore the runDir setting for now. You can actually put anything here, but “eclipse” is recommended if you are using eclipse as the IDE. Previously, "assetDir" was used. It is now deprecated, so use "runDir" in your project.



    Step6: Hold shift while right clicking on an empty space inside the folder, and choose “open command window here” from the dropdown menu. Type the usual stuff that everybody tells you to, but replace “gradlew.bat” with “gradle”. So first, type “gradle setupDecompWorkspace”. After the long waiting, type “gradle runClient”. Tada! You never downloaded forge nor minecraft, but you started a minecraft client with forge installed!


    Alright, I took you a long way to do the same thing that most people successfully did in half the time. Why does this matter? You now know much better about Gradle and Forge! You know that Forge's source distribution isn't really “source”, it is just scripts telling your computer how to download and compile the actually source. The next time you need to setup a project and upload it to github, you don't have to download Forge anymore, just type in the build script above, and you are set. Of course, please still include the Forge's credit file to show your respect.

    Update:
    some more explanation.
    add the notice that "assetDir" is deprecated.
    change "forgeFS" to "forge". They can be used interchangeably.
    Posted in: Mapping and Modding Tutorials
  • 0

    posted a message on Throwable Bricks Mod - New Overhaul! And... Brick Cannons? Sweet!
    sorry I misspelled :P . I meant "stunning". I must have done too much reading on stunted growth of plants...
    Posted in: Minecraft Mods
  • To post a comment, please or register a new account.