Author Archives: Elliott

May 31st Event

Our next event is here!

Last month we covered some 3D CAD design, web publishing and Java with students in the 3 labs that we were running…this month we are going to pick up where we left off and add some new topics as well. The date is set, and we are looking forward to seeing everyone once again at the UMW Stafford campus!

Our next event will take place on May 31st, and we will be covering the following topics:

  • GitHub Basics
  • Java
  • Python

No prior experience is necessary.

As always, parents are required to stay onsite with their children. This is how we keep these programs free and is not optional.

This event is open and free to kids aged 7-17.

Thanks to UMW, laptops will NOT be required for participation in this event! We will have access to computer labs with machines ready for student use. Feel free to bring your own laptop if you have one however.

Mentors, please regsiter as well.

Click here to register!

 

Anatomy of a Bug

Those who were at our last event in the Minecraft Mod room might remember this curious site we came across:

bug

Clearly something has gone wrong here…

Apparently we created a recipe which takes no ingredients. Looks like we have a bug in our software. This actually illustrates an important lesson to learn as a developer:

All software has bugs.

Whether your software is complex, simple, hardly used, or the most popular app in the app store, it has bugs. Even the most intensive testing will not find all bugs that exist in a piece of software.

So, now that we have a bug we want to figure out why it’s happening. I tried making small changes to the code, removing code to simplify what was going on, and change working code to be more like the broken code all to try and diagnose what went wrong. Finally I came across this piece of code:

String row1 = ((input[0][0] != null) ? "a" : " ") + ((input[0][1] != null) ? "a" : " ") + ((input[0][2] != null) ? "c" : " ");
String row2 = ((input[1][0] != null) ? "d" : " ") + ((input[1][1] != null) ? "e" : " ") + ((input[1][2] != null) ? "f" : " ");
String row3 = ((input[2][0] != null) ? "g" : " ") + ((input[2][1] != null) ? "h" : " ") + ((input[2][2] != null) ? "i" : " ");

Do you see something which looks out of place? If you can say your ABC’s you might… Even though you may not know what’s going on here, (using the ternary operator as a quick way to evaluate if/then/else statements) you still may be able to spot the error

That’s right. I copied and pasted this code a number of times instead of typing it all out (refer to the lazy/efficient programmer discussion we had). I managed to not update the second “a” reference which should be a “b”. This was causing recipes which had an ingredient in the position [0][1] to not be created properly. With that simple fix in place now we can see:

fixed

Much Better!

I was curious how long this bug existed so I looked at the code’s history in GitHub and found out it has been there ever since the code was first committed, about a year ago. How could this bug have existed for so long? Well, this specific use was simply never tested.

Bugs happen! They can be frustrating, but they can also be fixed. I fixed this one and committed it to our source code with a nice message (“Fixed recipe bug (dupe ‘a’ keys)”) so that hopefully nobody will encounter this bug again. Or if they do, then can look through the history and found out how to fix it!

In the comments to this post, tell of a time you found a software bug. What happened? Could you reproduce it? Have you found any bugs in Minecraft?

And as promised, here is an excellent tutorial for getting your Minecraft Modding environment setup for Minecraft 1.7:

Follow Up: Greenfoot

Greenfoot was a huge success at our March event. Be sure to download Greenfoot to a computer at home so you can try it out on your own! You can download Greenfoot here.

Like Scratch, Greenfoot has an awesome community around it who have shared some excellent creations. Check out this Animated Logo, A Simple Game, A More Complicated Game, and many more from the Greenfoot site.

This month’s challenge is to download a Greenfoot scenario take a look at what it does and modify it yourself. If it’s a logo, change the wording. If it’s a game, make sure you have the highest score ;).

Leave a comment to this post with what you came up with!

Dojo Event March

Our next event is coming up March 8th. Make your reservation here:

https://www.eventbrite.com/e/fredx-coder-dojo-march-8th-2014-tickets-10527135947

  • Kids Learning Code w/ Scratch Lesson
  • Intro to 3D Scanning & Printing Lesson
  • Java – Minecraft Dev Continued
  • More!

Join us and get your code on!

Getting your Minecraft Modding Environment Setup

This post is a bit out of date. Check out the new easier method here.

Here are some basic instructions for getting a Minecraft modding environment setup:

  • Download PC.zip or Mac.zip
  • Extract the contents
  • Extract Eclipse
  • Run Java JDK installation
  • Extract Forge
  • Run forge/install.cmd (or install.sh for Mac). This will take a few minutes to complete.
  • Extract BaseMod. Copy the “com” and “assets” folders to our mod to forge/mcp/src/minecraft. (It’s okay to overwrite any existing files)
  • Open your Eclipse folder and double click eclipse.exe (windows) or eclipse (mac).
  • Click File -> Import…
  • Search for Existing and double click “Existing Projects into Workspace”. Click Next.
  • Click “Browse” and go to your forge/mcp/eclipse/ folder. Click Finish.
  • Eclipse will import the project. Once finished you can click the green play icon which says “Run”. This will run Minecraft from the source that forge decompiled with our mod in there.
  • If you want to look at our BaseMod source code expand the “Minecraft” -> “src” -> “com.fredxcoders.dojo.mod” folders. BaseMod.java has our custom recipe to turn dirt into an instance of our custom block.

Updating to our latest mod code:

  • Go to our GitHub page here and click the “Download Zip” button in the bottom right.
  • Extract the contents of the zip and copy the “com” and “assets” folders to our mod to forge/mcp/src/minecraft. (It’s okay to overwrite any existing files).
  • If eclipse is open click the top “Minecraft” folder and hit F5. If it’s not, open eclipse.
  • Eclipse will now have our latest source code in it.

Lesson: Minecraft Ore Generation

Let’s recap what we’ve done so far. We’ve made custom recipes, custom blocks, and we made those blocks manipulate the Minecraft world around us. Now it’s time to make those blocks spawn naturally in the world.

In Minecraft all blocks have rules which control how and where they spawn. The block spawning process is determined the first time a chunk is loaded. In Minecraft a chunk is 16x 16 x 256 blocks. When you generate a new world some chunks around the spawn area are created and as you explore you will create and load more chunks.

You’ll want to download the latest zip of our mod here. Once downloaded open the zip file. Copy the “com” and “assests” folders to your folder “forge/mcp/src/minecraft/” (overwriting any previous files in there). Now fire up Eclipse and let’s take a look at the new code.

If you open up our com.fredxcoders.dojo.mod.BaseMod.java file you may miss the change we did here but it’s an important one.

EventManager eventManager = new EventManager();
GameRegistry.registerWorldGenerator(eventManager);

What we’ve done is create an EventManager object and register it as a WorldGenerator. What is an EventManager you ask? Well let’s take a look at that then. Open up com.fredxcoders.dojo.mod.managers.EventManager.java. You should see something like this:

package com.fredxcoders.dojo.mod.managers;</code>

import java.util.Random;

import com.fredxcoders.dojo.mod.BaseMod;

import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.feature.WorldGenMinable;
import cpw.mods.fml.common.IWorldGenerator;

public class EventManager implements IWorldGenerator{

@Override
public void generate(Random random, int chunkX, int chunkZ, World world,
IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {

//world.provider.dimensionId -1 is nether, 0 is overworld, 1 is end
if(world.provider.dimensionId == 0){
generateOverworld(world, random,chunkX*16, chunkZ*16);
}
}

private void generateOverworld(World world, Random random, int x, int z) {
int maxX = 16; //minX is one, so setting this to 16 says all of the x ranges can be used
int maxZ = 16; //minY is one, so setting this to 16 says all of the y ranges can be used
int maxVeinSize = 4 + random.nextInt(5); //this means each patch of our blocks will be between 4 and 8 large
int chancesToSpawn = 50; //How many times our ore can spawn in one chunk
int minY = 15; //how low the ore can spawn
int maxY = 80; //how high the ore can spawn
this.addOreSpawn(BaseMod.MY_BLOCK, world, random, x, z, maxX, maxZ, maxVeinSize, chancesToSpawn, minY, maxY);
}

/**
* Adds an Ore Spawn to Minecraft. Simply register all Ores to spawn with this method in your Generation method in your IWorldGeneration extending Class
*
* @param The Block to spawn
* @param The World to spawn in
* @param A Random object for retrieving random positions within the world to spawn the Block
* @param An int for passing the X-Coordinate for the Generation method
* @param An int for passing the Z-Coordinate for the Generation method
* @param An int for setting the maximum X-Coordinate values for spawning on the X-Axis on a Per-Chunk basis
* @param An int for setting the maximum Z-Coordinate values for spawning on the Z-Axis on a Per-Chunk basis
* @param An int for setting the maximum size of a vein
* @param An int for the Number of chances available for the Block to spawn per-chunk
* @param An int for the minimum Y-Coordinate height at which this block may spawn
* @param An int for the maximum Y-Coordinate height at which this block may spawn
**/
public void addOreSpawn(Block block, World world, Random random, int blockXPos, int blockZPos, int maxX, int maxZ, int maxVeinSize, int chancesToSpawn, int minY, int maxY)
{
int maxPossY = minY + (maxY - 1);
assert maxY &gt; minY: "The maximum Y must be greater than the Minimum Y";
assert maxX &gt; 0 &amp;&amp; maxX &lt;= 16: "addOreSpawn: The Maximum X must be greater than 0 and less than 16"; assert minY &gt; 0: "addOreSpawn: The Minimum Y must be greater than 0";
assert maxY &lt; 256 &amp;&amp; maxY &gt; 0: "addOreSpawn: The Maximum Y must be less than 256 but greater than 0";
assert maxZ &gt; 0 &amp;&amp; maxZ &lt;= 16: "addOreSpawn: The Maximum Z must be greater than 0 and less than 16";

int diffBtwnMinMaxY = maxY - minY;
for(int x = 0; x &lt; chancesToSpawn; x++)
{
int posX = blockXPos + random.nextInt(maxX);
int posY = minY + random.nextInt(diffBtwnMinMaxY);
int posZ = blockZPos + random.nextInt(maxZ);
(new WorldGenMinable(block.blockID, maxVeinSize)).generate(world, random, posX, posY, posZ);
// System.out.println("We just spawned a MY_BLOCK! [" + x + "]");
}
}
}

Let’s go over what this code is doing. First you can see that our EventManager object Implements IWorldGenerator. The IWorldGenerator class was created by Minecraft to help control how blocks are generated. When we implement that interface we have to include one method:

public void generate(Random random, int chunkX, int chunkZ, World world,
IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {

This is the method Minecraft is going to execute when it goes to create a new chunk. What does this method do? Well, it checks  if the current world.provider.dimensionId is 0 (according to the comment that means that the player generating the new chunk is in the overworld) and then calls the generateOverworld method.

private void generateOverworld(World world, Random random, int x, int z) {
int maxX = 16; //minX is one, so setting this to 16 says all of the x ranges can be used
int maxZ = 16; //minY is one, so setting this to 16 says all of the y ranges can be used
int maxVeinSize = 4 + random.nextInt(5); //this means each patch of our blocks will be between 4 and 8 large
int chancesToSpawn = 50; //How many times our ore can spawn in one chunk
int minY = 15; //how low the ore can spawn
int maxY = 80; //how high the ore can spawn
this.addOreSpawn(BaseMod.MY_BLOCK, world, random, x, z, maxX, maxZ, maxVeinSize, chancesToSpawn, minY, maxY);
}

This method sets a bunch of parameters for how our ore will be spawned (check the comments for what each one does). Finally after the parameters are set it calls addOreSpawn which is a nice little method I borrowed from wuppy29 who has some great tutorials here. We pass BaseMod.MY_BLOCK (our custom block) to addOreSpawn so that it can be added to the chunk.

Now that we’ve looked at the code let’s fire up Minecraft and see if we can spot our ores in the wild! You’ll probably want to create a new world and hit  F3 to show your coordinated. Make sure your “y” is in the minY and maxY range specified in generateOverworld when looking for the ore. It also helps to be on creative mode.

Once you’ve spotted some ore and verify these changes worked, start playing around with the parameters in generateOverworld. Here are some tips:

    1. Make the ore spawn only in high places or only low.
    2. Make it rare but concentrated in large clusters or bountiful but in small amounts.
    3. Manage to crash Minecraft with your changes. Awesome! Write down your steps. Knowing how to crash a program will help you figure out how not to.
    4. What happens if you don’t start with a fresh world after each change? When do your changes start happening?
    5. Take a screenshot of something that looks cool.
    6. Uncomment this line. When do you notice these statements print to your console in Eclipse?:
// System.out.println("We just spawned a MY_BLOCK! [" + x + "]");

Extra credit:

  1. Our code currently spawns our custom block. What if we want to spawn some existing blocks in new places or next to our custom block. How could we do that?
  2. In our generate method there is a comment which references the nether. See if you can get our custom block to spawn there as well.

February Event Checklist

NOTE: I originally posted bad links to the download. I have corrected them now!

Our February event is just a couple of days away so here’s a checklist to go over to make sure you’re prepared:

– Bring a laptop! One per child is ideal, but we can pair program where we need to too.

– Have a copy of Minecraft. One per laptop! If you haven’t purchased Minecraft you can do so here:https://minecraft.net/

– Download the zip file of the software we use. Even if you’ve been to an event before go ahead and download the latest as some software may have changed since your last visit. Download the appropriate version for your machine: Windows or Mac.

Feel free to post any questions you have as a comment here. See you Saturday!

Getting Back in the Coding Groove

Howdy! For some of you, it’s been awhile since you were coding. For others you may be getting ready for your first Dojo event. In either case I’d like to offer a great way to get into the coder groove:

Hour of Code

Hour of code is an initiative to get kids a taste of learning to write code and parallels the goal of our Dojo. There are a bunch of self paced lessons which you can do in about an hour. There are some pretty heavy hitters behind the initiative (Bill Gates, Mark Zuckerberg, etc) and some really great modules (anyone like Angry Birds?).

Still not sold? Check this video out: