I have been looking around my code to see if I could find why the server crashes, but I can't find it.
Here is the console output of the server before it crashes:
[21:33:26] [main/INFO] [GradleStart]: Extra: []
[21:33:26] [main/INFO] [GradleStart]: Running with arguments: [--tweakClass, cpw.mods.fml.common.launcher.FMLServerTweaker, --tweakClass, net.minecraftforge.gradle.GradleStartCommon$GradleStartTweaker]
[21:33:26] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLServerTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Using primary tweak class name cpw.mods.fml.common.launcher.FMLServerTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.GradleStartCommon$GradleStartTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLServerTweaker
[21:33:26] [main/INFO] [FML]: Forge Mod Loader version 7.10.85.1240 for Minecraft 1.7.10 loading
[21:33:26] [main/INFO] [FML]: Java is Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_05, running on Windows 8.1:amd64:6.3, installed at C:\Program Files\Java\jre8
[21:33:26] [main/INFO] [FML]: Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation
[21:33:26] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.GradleStartCommon$GradleStartTweaker
[21:33:26] [main/INFO] [GradleStart]: Injecting location in coremod cpw.mods.fml.relauncher.FMLCorePlugin
[21:33:26] [main/INFO] [GradleStart]: Injecting location in coremod net.minecraftforge.classloading.FMLForgePlugin
[21:33:26] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLDeobfTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[21:33:26] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[21:33:26] [main/ERROR] [FML]: The binary patch set is missing. Either you are in a development environment, or things are not going to work!
[21:33:28] [main/ERROR] [FML]: FML appears to be missing any signature data. This is not a good thing
[21:33:28] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[21:33:28] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLDeobfTweaker
[21:33:29] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.TerminalTweaker
[21:33:29] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.TerminalTweaker
[21:33:29] [main/INFO] [LaunchWrapper]: Launching wrapped minecraft {net.minecraft.server.MinecraftServer}
[21:33:32] [main/WARN] [FML]: =============================================================
[21:33:32] [main/WARN] [FML]: MOD HAS DIRECT REFERENCE System.exit() THIS IS NOT ALLOWED REROUTING TO FML!
[21:33:32] [main/WARN] [FML]: Offendor: net/minecraft/server/gui/MinecraftServerGui$1.windowClosing(Ljava/awt/event/WindowEvent;)V
[21:33:32] [main/WARN] [FML]: Use FMLCommonHandler.exitJava instead
[21:33:32] [main/WARN] [FML]: =============================================================
[21:33:32] [Server thread/INFO]: Starting minecraft server version 1.7.10
[21:33:32] [Server thread/INFO] [MinecraftForge]: Attempting early MinecraftForge initialization
[21:33:32] [Server thread/INFO] [FML]: MinecraftForge v10.13.2.1240 Initialized
[21:33:32] [Server thread/INFO] [FML]: Replaced 182 ore recipies
[21:33:32] [Server thread/INFO] [MinecraftForge]: Completed early MinecraftForge initialization
[21:33:32] [Server thread/INFO] [FML]: Searching D:\Modstuffs 2\Astral\eclipse\mods for mods
[21:33:36] [Server thread/INFO] [FML]: Forge Mod Loader has identified 4 mods to load
[21:33:36] [Server thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, spectrum] at CLIENT
[21:33:36] [Server thread/INFO] [FML]: Attempting connection with missing mods [mcp, FML, Forge, spectrum] at SERVER
[21:33:37] [Server thread/INFO] [FML]: Processing ObjectHolder annotations
[21:33:37] [Server thread/INFO] [FML]: Found 341 ObjectHolder annotations
[21:33:37] [Server thread/INFO] [FML]: Configured a dormant chunk cache size of 0
[21:33:37] [Server thread/INFO] [FML]: Applying holder lookups
[21:33:37] [Server thread/INFO] [FML]: Holder lookups applied
[21:33:37] [Server thread/INFO]: Loading properties
[21:33:37] [Server thread/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.
[21:33:37] [Server thread/WARN] [FML]: Can't revert to frozen GameData state without freezing first.
[21:33:37] [Server thread/INFO] [FML]: Applying holder lookups
[21:33:37] [Server thread/INFO] [FML]: Holder lookups applied
[21:33:37] [Server thread/INFO] [FML]: The state engine was in incorrect state POSTINITIALIZATION and forced into state SERVER_STOPPED. Errors may have been discarded.
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
I've been looking around a bit for how to use the collisionRayTrace() method in Block and I haven't been able to find out how it works. I'm trying to make a block that shoots lines of particles in a random direction. I think I know how the vectors work, but I don't know how to use the in collisionRayTrace(). If anyone could help out it would be very appreciated.
Time: 11/30/14 7:15 PM
Description: Exception in server tick loop
java.lang.NullPointerException: Exception in server tick loop
at com.astral.tileentity.TEStar.onServerTick(TEStar.java:73)
at cpw.mods.fml.common.eventhandler.ASMEventHandler_6_TEStar_onServerTick_ServerTickEvent.invoke(.dynamic)
at cpw.mods.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:54)
at cpw.mods.fml.common.eventhandler.EventBus.post(EventBus.java:138)
at cpw.mods.fml.common.FMLCommonHandler.onPreServerTick(FMLCommonHandler.java:260)
at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:603)
at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:485)
at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:752)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
-- System Details --
Details:
Minecraft Version: 1.7.10
Operating System: Windows 8.1 (amd64) version 6.3
Java Version: 1.8.0_05, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 782933296 bytes (746 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
FML: MCP v9.05 FML v7.10.85.1240 Minecraft Forge 10.13.2.1240 4 mods loaded, 4 mods active
mcp{9.05} [Minecraft Coder Pack] (minecraft.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
FML{7.10.85.1240} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.2.1240.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
Forge{10.13.2.1240} [Minecraft Forge] (forgeSrc-1.7.10-10.13.2.1240.jar) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
astral{0.0.1} [Astral] (bin) Unloaded->Constructed->Pre-initialized->Initialized->Post-initialized->Available->Available->Available->Available
Profiler Position: N/A (disabled)
Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
Player Count: 0 / 8; []
Type: Integrated Server (map_client.txt)
Is Modded: Definitely; Client brand changed to 'fml,forge'
[19:15:39] [Client thread/INFO] [STDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:393]: #@[email protected]# Game crashed! Crash report saved to: #@[email protected]# .\crash-reports\crash-2014-11-30_19.15.39-server.txt
AL lib: (EE) alc_cleanup: 1 device not closed
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release
I tried putting a null check in, didn't change anything.
EDIT: AND WOW I am the biggest derp. I totally forgot about OnUpdate()
It's fixed now
I don't know? I'm pretty new to modding, so I guess I accidentally made it static. I changed it to non-static and it makes the internal number not change, instead of making them all change.
I'm trying to make a energy storage block that holds a certain amount of power and is drained by an altar. How it works now it that I use the altar and it gives the storage overload, which then if right clicked on with a wand, the overload will be dissipated in exchange for loss of internal power. The overload is stored in metadata, whereas power is stored in an integer / NBT. Whenever I exchange the overload for power loss, it works, but it also makes all other power storage (stars) in the world lose power as well, including ones that weren't placed down.
Star Block Code:
package com.astralmagicmod.block;
import java.util.Random;
import ibxm.Player;
import com.astralmagicmod.item.AMItem;
import com.astralmagicmod.tileentity.TileEntityBasinWater;
import com.astralmagicmod.tileentity.TileEntityPrimitiveAltar;
import com.astralmagicmod.tileentity.TileLesserStar;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.play.client.C01PacketChatMessage;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;
public class LesserStar extends BlockContainer {
protected LesserStar(Material glass) {
super(glass);
this.setLightLevel(1.0F);
}
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_)
{
return AMItem.depletedShard;
}
public int quantityDropped(Random p_149745_1_)
{
return 4;
}
public static boolean canRecharge = true;
public static int maxpower = 2;
public static float vibrancy = 1.0F;
private String text;
public boolean onBlockActivated(final World p_149727_1_, final int p_149727_2_, final int p_149727_3_, final int p_149727_4_, EntityPlayer p_149727_5_, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_)
{
if(!p_149727_1_.isRemote)
{
TileLesserStar t = (TileLesserStar) p_149727_1_.getTileEntity(p_149727_2_, p_149727_3_, p_149727_4_);
//t.processActivate(p_149727_1_, p_149727_2_, p_149727_3_, p_149727_4_, p_149727_5_, p_149727_6_, p_149727_7_, p_149727_8_, p_149727_9_);
}
if (p_149727_1_.isRemote)
{
return true;
}
else
{
ItemStack var10 = p_149727_5_.inventory.getCurrentItem();
if (var10 == null)
{
return true;
}
else
{
TileLesserStar tileStar = (TileLesserStar) p_149727_1_.getTileEntity(p_149727_2_, p_149727_3_, p_149727_4_);
int powerStored = tileStar.getPowerStored();
if(var10.getItem() == AMItem.starMirror)
{
int overloadint = p_149727_1_.getBlockMetadata(p_149727_2_, p_149727_3_, p_149727_4_);
String overloadString = "Overload: " + String.valueOf(overloadint);
String overloadMax = "Nova: 3";
String charge = "Internal Charge: " + String.valueOf(powerStored);
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(overloadString, new Object[0]));
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(overloadMax, new Object[0]));
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(charge, new Object[0]));
}
if(var10.getItem() == AMItem.astralWand)
{
int overloadint = p_149727_1_.getBlockMetadata(p_149727_2_, p_149727_3_, p_149727_4_);
powerStored = powerStored - overloadint;
p_149727_1_.setBlock(p_149727_2_, p_149727_3_, p_149727_4_, AMBlock.lesserStar, 0, 2);
if(powerStored < 0)
{
p_149727_1_.setBlock(p_149727_2_, p_149727_3_, p_149727_4_, AMBlock.emptyStar);
p_149727_1_.removeTileEntity(p_149727_2_, p_149727_3_, p_149727_4_);
}
}
}
}
return true;
}
public TileEntity createNewTileEntity(World par1World, int integer)
{
try
{
return new TileLesserStar();
}
catch (Exception var3)
{
throw new RuntimeException(var3);
}
}
}
Star Tile Entity Block:
package com.astralmagicmod.tileentity;
import com.astralmagicmod.block.AMBlock;
import com.astralmagicmod.item.AMItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.world.World;
public class TileLesserStar extends TileEntity{
public static int powerStored = 10;
public int powerMax = 10;
public int vibrancy = 10;
private String energyOutText = Integer.toString(powerStored);
public boolean processActivate(final World p_149727_1_, final int p_149727_2_, final int p_149727_3_, final int p_149727_4_, EntityPlayer p_149727_5_, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_)
{
if (p_149727_1_.isRemote)
{
return true;
}
else
{
ItemStack var10 = p_149727_5_.inventory.getCurrentItem();
if (var10 == null)
{
return true;
}
else
{
TileLesserStar tileStar = (TileLesserStar) p_149727_1_.getTileEntity(p_149727_2_, p_149727_3_, p_149727_4_);
if(var10.getItem() == AMItem.starMirror)
{
int overloadint = p_149727_1_.getBlockMetadata(p_149727_2_, p_149727_3_, p_149727_4_);
String overloadString = "Overload: " + String.valueOf(overloadint);
String overloadMax = "Nova: 3";
String charge = String.valueOf(powerStored);
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(overloadString, new Object[0]));
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(overloadMax, new Object[0]));
p_149727_5_.addChatComponentMessage(new ChatComponentTranslation(charge, new Object[0]));
}
if(var10.getItem() == AMItem.astralWand)
{
int overloadint = p_149727_1_.getBlockMetadata(p_149727_2_, p_149727_3_, p_149727_4_);
powerStored = powerStored - overloadint;
p_149727_1_.setBlock(p_149727_2_, p_149727_3_, p_149727_4_, AMBlock.lesserStar, 0, 2);
if(powerStored < 0)
{
p_149727_1_.setBlock(p_149727_2_, p_149727_3_, p_149727_4_, AMBlock.emptyStar);
p_149727_1_.removeTileEntity(p_149727_2_, p_149727_3_, p_149727_4_);
}
}
}
}
return true;
}
public int getPowerStored()
{
return powerStored;
}
public void writeToNBT(NBTTagCompound var1)
{
var1.setInteger("powerStored", this.powerStored);
super.writeToNBT(var1);
}
public void readFromNBT(NBTTagCompound var1)
{
this.powerStored = var1.getInteger("powerStored");
super.readFromNBT(var1);
}
}
Hello everybody, Apuppy120 here to bring my first published mod! I made this in a few days (Yes it's a small mod) and I like the result. Just a quick note before you proceed: I made this mod to get rid of all my mod crazies out of my system. I try to keep my other mod that I'm working on serious, so I used this to siphon out that craziness. Now to proceed.
This mod is all about turtles. I could probably leave it at that, but I'm going to elaborate about the contents a little bit.
This mod is all about turtles. Some of them have hats. You can get materials from the turtles to make super overpowered gear that essentially makes you unbeatable. Note that all the gear costs over 12 blocks of diamond. I would suggest getting the Turtle Propeller Pack first. Once you track down a propeller turtle, you can feed it a piece of raw fish. It's hunger is now satisfied, and will now be willing to cooperate (as much as it can, anyways). You now right click on it with a leather chestplate to obtain the Turtle Propeller Pack. You wear it on your torso slot and the propeller that the turtle wears assist your jump. Otherwise it is essentially just a leather chestplate with a crazed flight-turtle strapped to your back. Once you collect enough turtle shells (and diamonds) you can create the Turtle Armor. You make them by putting turtle shells in a sideways "H" in the crafting table, and two pieces of the respective diamond armor piece in the two remaining slots. You can combine the Turtle Chestplate with the Turtle Propeller Pack to make the Reinforced Propeller Pack by placing the Propeller Pack in the top middle slot, a "U" of turtle shells, and the Turtle Chestplate in the center. It is now a crazed flight-turtle strapped to the back of a indestructible (Mostly) chestplate. You can then make the turtle tools. In order to make the paxel, you need 3 blocks of diamond, a diamond pick, axe and shovel, two turtle shells, and a nether star. You will need the same resources for the sword, but the diamond swords instead of tools. You put them in this shape: Pick-Axe-Shovel on top. A row of diamond blocks in the middle, and Shell-Star-Shell on the bottom. Do the same for the blade and you now have the most overpowered stuff in the game (That I know of.)
Based on what you're trying to achieve, I take it you're wanting to do something every tick in game? Like, have your code constantly running?
If so, while loops won't help. The game runs on a thread, which is a managed loop, sort of. Whenever you execute a loop, you interrupt the game's thread, and it won't start back up till your loop is broken out of (either by issuing a break command or by ending the loop naturally). Because you've got an infinite loop, your loop never stops. So the JVM is stuck inside your code executing it over and over, thus, it can't call the rest of the game's code, therefore, the game locks up on you.
Now, before I explain what you SHOULD do, I'll explain how the game works internally. Every time the loop reiterates through the code (reloops through the code, if you will), the game has a bunch of event-like methods and classes responding. This concept is known as ticking. A tick is essentially one update to the game's code. The thread is clocked to 20 times per second, so the game ticks 20 times per second, ie the code is being executed and reran 20 times every second.
Forge has a feature called events. An event is exactly as it sounds, it's an event that happens in the game, whether that be hitting a block or hurting an entity, or more internal and advanced things like chunks loading and unloading, or an entity being constructed. You can subscribe any method of yours to a specific event (or set of events that have a main common event, say any living entity event, they all have a common base, LivingEvent IIRC, you can subscribe to this to run your code on ANY event that is of this type). When you subscribe to it, and register the class your method and subscription is in, it gets added to the Event Bus (basically a list, if you will). When an event happens in the game, Forge goes through and fires all subscribed methods that are subscribed to this event, so your code will be ran when the event you're subscribed to occurs.
Now, Forge has this thing called a TickEvent, which is event that is fired every tick. You can use this to automatically run any code you wish whenever the game ticks / updates.
Now, I do realise that you said you solved the issue, however I thought I should perhaps suggest a better / more official way of doing so. IMO, running your code on a separate thread, especially for your purpose, is highly inefficient, as you need to take into consideration things such as synchronisation, fields, instances, etc, at the end of the day, IMO way too much work for what it's worth, when you could do something which is much easier and more official and supported, which would give you a better effect and better performance when you get down to it.
Thanks! I hadn't quite understood how Events worked, so I kinda avoided them until I learned how. Turns out I needed them for this. I currently have it looping every ten-some minutes with a delayed while loop, though this would probably make the code neater and less laggy.
Right now it sounds really interesting! o:
I wish there would be some pics already! >.<
Sorry, but I'm coding in the order of actual progression, and the next thing is the Altar. The Altar is a multiblock, and I'm still learning how to code multiblocks.
Of a Sort. I'm mostly going to be updating this post as this stuff gets programmed. There will be an added dimension: The Astral Plane. I'll give more info about it later, though Astral Projection might be something cool to do.
0
It works now.
0
Here is the console output of the server before it crashes:
0
0
I tried putting a null check in, didn't change anything.
EDIT: AND WOW I am the biggest derp. I totally forgot about OnUpdate()
It's fixed now
0
It also crashes on this:
I also tried using WorldTickEvent but it also crashed.
Here is the code:
Also, the TEStar class is registered for events.
0
0
0
Star Block Code:
Star Tile Entity Block:
0
0
0
This mod is all about turtles. I could probably leave it at that, but I'm going to elaborate about the contents a little bit.
This mod is all about turtles. Some of them have hats. You can get materials from the turtles to make super overpowered gear that essentially makes you unbeatable. Note that all the gear costs over 12 blocks of diamond. I would suggest getting the Turtle Propeller Pack first. Once you track down a propeller turtle, you can feed it a piece of raw fish. It's hunger is now satisfied, and will now be willing to cooperate (as much as it can, anyways). You now right click on it with a leather chestplate to obtain the Turtle Propeller Pack. You wear it on your torso slot and the propeller that the turtle wears assist your jump. Otherwise it is essentially just a leather chestplate with a crazed flight-turtle strapped to your back. Once you collect enough turtle shells (and diamonds) you can create the Turtle Armor. You make them by putting turtle shells in a sideways "H" in the crafting table, and two pieces of the respective diamond armor piece in the two remaining slots. You can combine the Turtle Chestplate with the Turtle Propeller Pack to make the Reinforced Propeller Pack by placing the Propeller Pack in the top middle slot, a "U" of turtle shells, and the Turtle Chestplate in the center. It is now a crazed flight-turtle strapped to the back of a indestructible (Mostly) chestplate. You can then make the turtle tools. In order to make the paxel, you need 3 blocks of diamond, a diamond pick, axe and shovel, two turtle shells, and a nether star. You will need the same resources for the sword, but the diamond swords instead of tools. You put them in this shape: Pick-Axe-Shovel on top. A row of diamond blocks in the middle, and Shell-Star-Shell on the bottom. Do the same for the blade and you now have the most overpowered stuff in the game (That I know of.)
Download:
1.7.2
0
It's all like Sonic the Hedgehog in here...
0
Thanks! I hadn't quite understood how Events worked, so I kinda avoided them until I learned how. Turns out I needed them for this. I currently have it looping every ten-some minutes with a delayed while loop, though this would probably make the code neater and less laggy.
0
Sorry, but I'm coding in the order of actual progression, and the next thing is the Altar. The Altar is a multiblock, and I'm still learning how to code multiblocks.
You can still use Astral Craft, mine is called Astral Magic, and might get a name change in the future.
0
Of a Sort. I'm mostly going to be updating this post as this stuff gets programmed. There will be an added dimension: The Astral Plane. I'll give more info about it later, though Astral Projection might be something cool to do.
Also, I hate multiblocks.