Showing posts with label higherpower. Show all posts
Showing posts with label higherpower. Show all posts

Wednesday, April 9, 2014

HigherPower - Oh, Right

While in the car today, a realization struck me concerning HigherPower's increased world generation time. (In the middle of all the crazy busyness going on in my life right now, I don't have time to actually write about important things here.)

A configuration file option tells the HigherPower world generators how many ores of each type to place in each chunk. If I remember correctly, 200 Fleexium and 2 Eethur ores are generated per chunk. It doesn't take a lot of time to pick 200 random locations and try to put an ore block there - but what does take a lot of time is continuing the pick random locations until 200 blocks are filled with ore. This takes even longer for Eethur, which has extremely specific spawning conditions.

Now I feel somewhat silly. Instead of trying to generate a maximum of 200 ores per chunk, I'm forcing it to place all 200 somewhere. With the 1.7 world generator bringing a lot more variety in the underground block types, this resulted in a huge slowdown for HigherPower, which only places its ores in regular stone. I suppose I'll soon be changing the code to use a maximum of some higher number.

Mental program optimization! Gedankenexperiments!

Sunday, April 6, 2014

HigherPower - Network Time

Well, I decided it's finally time to look at some Forge tutorials and get HigherPower's custom packets and network functionality back together. Getting the infrastructure for it set up was a breeze; I love Netty! I still need to figure out how to actually move my data into The New Way, but I'm guessing NBT serialization hasn't changed terribly much.

Instead of doing what I planned to do, I tested some considerably less related stuff. The Furnace Sensor, one of the most difficult things to implement, surprisingly didn't have any huge problems. It did cause a crash, but that was because I had some something obviously silly with Block objects that caused a null pointer exception. After repairing that, the sensor worked just like before. (Even the incredibly inconvenient GUI continued to be inconvenient!)

The Lawn Mower, possibly the most hacked-up glob of code I've ever written, is another story. For some reason, it decided to pull stacks of pumpkin seeds, redstone torches, and various flowers out of nowhere. Inserting null checks at various places fixed that, but the machine remained the super buggy thing it always had been. While trying to tweak that, I did somehow cause it to create a huge, writhing, expanding wall of lawn mower blocks whenever one started moving. I fixed that and also the old bug that made it not drop its contents when destroyed while moving.

Saturday, April 5, 2014

HigherPower - Legit Names

Today, I continued to clean up the HigherPower code base after the move to Forge for v1.7. This involved much renaming of files and a little bit of JSON file writing.

Really, most of the time I spent was replacing @ForgeSubscribe and @EventHandler with @SubscribeEvent and liberally decorating methods with @Override. More functionality is intact than I expected; even the super-hacked /genhere command still works. The wireless redstone blocks worked almost immediately, except that their Creative inventory icons were rotated the wrong way. There were a few inconsistencies with implementations of _HPBlockContainer versus BlockContainer, but those have all been made better.

It did take me a while to figure out how to fix the PSY music discs. (Those are really important to the mod.) Apparently, SoundManager is no longer publicly accessible; sounds should be registered with ResourceLocation instances and JSON files placed in non-obvious locations.

Advanced data blocks continue to be broken, but other containers with GUIs surprisingly still work. For some reason, it now takes quite a bit longer to generate a new world, but I don't see any obvious performance problems in HigherPower's generators.

Ignoring such issues and instead being upset at blocks having wrong or default names, I embarked on a task of migrating the block constructors to the new string ID system. (It was actually at this point when I discovered the inconsistent class hierarchy.) Now, all of HigherPower's block classes register themselves in the constructor, saving me the hassle of doing that every fourth line.

The recommended way of gathering Nether Noir: a few stacks of glass and a diamond pick

HigherPower - A Huge Mess

With the switch to the Gradle build system and all the changes in vanilla Minecraft that came with version 1.7, HigherPower's code base became a huge mess of errors. I spent a couple hours today going through the at-least-sixty files and trying to get the project to build. Right now, I'm not concerned very much with things actually working; I just want it to run and not crash.

Most of the fixing was just mindless prepending of the letter I onto Icon and IconRegister. There were of course a bunch of things concerning the move towards string IDs, but I just had to change some variable types and some method calls.

What was really terrible, however, was the removal of public iterators in NBT tag objects. (They also, for some unimaginable reason, moved tag names into part of the parent tag's child map. This makes my life considerably more difficult when serializing.) It is no longer possible to just get a general list of all the subtags in an NBT list tag. I can get the number of items in the list, but I can't pull one out without knowing what type of things it contains - the methods are all specialized.

Also, the move to Netty for network handling has totally broken my advanced data machines, so I ended up commenting out pretty much everything about those. I'll deal with that later, once most everything else is actually functional again.

Registering items is mandatory now, so I had to put that registration instruction in the constructor for my items. I'm very happy that I have a class for such things. There are a lot of missing textures, but I can fix that by renaming the files to suit the new style.

Wednesday, April 2, 2014

HigherPower - Back to It

The Forge team decided to move to Gradle for code management. Therefore, every modder is forced to use that system, whether they like it or not. Until today, I could never get it to work - there was always some setup error or Eclipse couldn't find the files necessary to run the project. Somehow, everything lined up just right and Gradle built everything smoothly today.

Of course, like every Forge update, the update to Minecraft 1.7.2 broke everything. Literally all of my mod files have some sort of error in them. HigherPower is nowhere close to compiling, and a huge amount of its dependencies in Forge for 1.6.x are no longer extant or have changed names. (IconRegister, I'm looking at you.) Instead of the old way of doing packets, through the Forge networking infrastructure, it's integrated with Minecraft's Netty streams. That might actually make creating advanced GUIs less painful, but we shall see.

Message to Forge team: This is totally unacceptable. I understand you need to get compatibility with the new Minecraft versions, but you don't need to rename everything. Seriously, just a one-character change you made, probably with one keystroke, is going to require me to go through uncountable files to deal with. I had to go search the Internet and ask for help on IRC to figure out that the Configuration class moved namespaces. Your product, even though you don't get paid for it, is in use by hundreds if not thousands of developers around the world. Any minor inconvenience you cause is multiplied by that.

I know what I'll be doing the next few weeks. Isn't forced refactoring fun?

Friday, March 28, 2014

FMod - Better Find

One of the very few bad things about Abiathar was its "find" tool, the Tile Instance Locator. Before today, it would move the view window while searching to indicate where it found the tiles, which (in addition to being incredibly disorienting and inconvenient) did not work at all when bounded scrolling was enabled in the config file. So, I took a moment today to make it considerably less awful. It now works similarly to other editors' tile search mode, highlighting every instance of the selected combination of tiles. I wired it up to the plane state change event so it automatically recalculates the counts and rerenders the highlights when necessary.

I also adjusted the plane state menu items to make the consistent with the mode labels and added a nice "Help" menu with some links to various places where it might be possible to get help with Abiathar.

Wednesday, September 4, 2013

HigherPower - Improving /genhere

After noticing the setRandomHeight method of the StructureStart class, I decided to look into it.  It appears to be the way normal Minecraft provides variation in the height of Nether fortresses, strongholds, and abandoned mineshafts.  I used the location of the command sender to make the structure generate at a similar Y level to the player.  It has the unfortunate side effect of making villages fail to generate, which I will fix somehow sometime.

Monday, September 2, 2013

HigherPower - Fixed Packet Switch

I gave the Configurable Switch's tile entity function today.  It just iterates through the four sides, checks the state, and if it is an output face the incoming packet is sent there.  I also wrote up the Technical Manual documentation for it.
I'm kind of disappointed about the inability to control all the sides, but I might give the top and bottom states a hard-wired function.

Sunday, September 1, 2013

HigherPower - Fixed /genhere

I decided to finally fix the inability of HigherPower's /genhere to generate villages and scattered features.  It was pretty easy to do once I noticed the reason for its failure: MapGenVillage's getStructureStart calls a constructor with worldObj, which is not specified in its own constructor.  All I had to do was add a little more reflection to set that to the command sender's world.

This is the result of spamming "/genhere village" with some temples mixed in:

Tuesday, August 27, 2013

HigherPower - Failure Reason Understood

I feel pretty silly now for spending hours on the silverfish block and the Configurable Switch.  I was trying to use these huge (well, medium-sized) numbers as metadata, but only four bits are stored in the chunk.  That definitely explains the strange failures of a few sides of the CS and the limitations of the silverfish block.  So, I guess I won't be using metadata to store complicated information.  I don't know what I'm going to do about the silverfish block (besides disable it), but I did change the CS to only be configurable on the horizontal sides; the top and bottom are inert.  Though inconvenient, it has the advantage of looking cool in the inventory.

I'm gonna save meta
Only got four bits of storage
I, I, I'm packing, trying to compact it
Why doesn't Forge fix this? ♪

Sunday, August 25, 2013

HigherPower - Packet Switch

I ran into more Silverfish issues (Silverfissues if you will), so the Silverfish implanting machine is probably not going to work out.  For some reason, the cage blocks never take into account the posing metadata.  But I did start adding a new data processing machine, the Configurable Switch.  It will allow the player to choose which faces of a router-like block are inputs, outputs, or inert sides.  I don't want to use the tile entity to store the state of the faces, so I need to pack six two-bit numbers into the 16-bit metadata.  It's definitely possible, but I'm having a difficult time making it work.

Saturday, August 24, 2013

HigherPower - Silverfish Failures

I'm considering a new machine that will allow players to shove Silverfish into any block and then place that block in the world.  I have run into a strange problem with the silverfish-containing block: It looks as I want it to in the inventory (using the first 12 bits for block ID and the rest for metadata), but when it is placed it is the missing-texture block.  I did some experiments that showed that the issue was somewhere in the ItemBlock instance.  I saw that the metadata of the placed block is not the same as the block is in the inventory -- in fact, after being placed, its metadata becomes zero.  I think that is because the normal ItemBlock class does not respect metadata.  I tried to set the appropriate entry in Item.itemsList to an instance of ItemBlockWithMetadata, but that seemed to have no effect.  So, I guess I'll do some more meddling and if I can't fix the issue, I'll make the player inject the Silverfish in-world by placing the machine above each block.

I also added a possible sword aspect and a bow aspect.  Piercing (for swords) does extra damage to enemy armor, increasing exponentially per level.  Channeling (for bows) gathers Sharpness and Fire Aspect effects from swords in the shooter's inventory and applies them to the target, multiplying the effects by the level of aspect.

Sunday, August 18, 2013

HigherPower - More Superclassing

Once I started moving all directional functionality into a common superclass, I couldn't stop.  Today, I ripped out a few more instances of onPlacedBy and determineOrientation from new subclasses of _HPBlockContainer.  I might have caused some issues with the furnace sensor, but I need to do more testing to make sure everything's OK.  I also added the possibility of a nonorientable block to the constructor of _HPBlockContainer for the Lawn Mower and Absorber.  Unfortunately, my recent modifications to the Lawn Mower's Container results in the client being able to open a blank GUI for it when it's moving.  I'm thinking about using block metadata to determine whether the GUI can be opened by right-clicking.

Saturday, August 17, 2013

HigherPower - Sync Optimization

As I looked back on my networking code today, I thought that there must be a better way of synchronizing progress and energy data for machines; after all, vanilla doesn't do any such thing.  I looked at some vanilla machines' containers and saw the mysterious methods addCraftingToCrafters, updateProgressBar, and detectAndSendChanges.  Previously, I had assumed I could do better than that strange stuff, but I now see that my mess of dirty block lists, alternate networking channels, and constant updating.  Today, I went and ripped out that mess, replacing it with vanilla's style of keeping the sides in sync.  Also, I added a table of recipes and multiplications for the Absorber that includes all ores I know about.

Friday, August 16, 2013

HigherPower - Absorber

After school today, I added another machine to HigherPower!  It's a tier 1 (Fleexium) machine, so I used some existing code for combustion-driven machines.  This one, however, is a lot more complicated than any other machine.  It has five inputs: drill tip, left drill reinforcement, right drill reinforcement, solvent, and fuel.  The ore block to be processed is placed in the world under the Absorber. The solvent increases the chance of getting extra materials out of the ore block.  Though it is considerably more expensive to produce and operate, the Absorber has the advantages of producing more materials, automatically smelting, leaving behind a stone block, and being able to run on Nether Impurities.  While coding this machine, I discovered that my method of keeping the server and client synchronized is extremely overcomplicated.  I will be ripping out most of my networking code and replacing it with the built-in onInventoryChanged calls.

Wednesday, August 14, 2013

HigherPower - Superclassing

I decided to finally clean up a lot of HigherPower's classes by moving copy-pasted functionality to a common superclass.  That new class was _HPMachineTE, containing methods for ejecting items, performing NBT operations, giving information about the IInventory to Forge, and hooking HigherPower machines to slot-related events.  I did something similar with the Block classes that represented machines, creating _HPBlockContainer.  That class provides methods for orienting the block (with four or six directions), opening GUIs, creating and managing TileEntity instances, and spawning contents into the world when broken.  It really feels good to eliminate hundreds of lines of unnecessary code from a project.

Tuesday, August 13, 2013

HigherPower - Bi-Modal Ejector

Well, I finally added a tier 2 machine that's actually a machine to HigherPower.  This machine is the "bi-modal ejector", a combination of the dispenser and dropper that sports a few bonuses.  Instead of being triggered by redstone, it can only be fired with an appropriate packet coming in on the input face.  Changing between the two modes (dispenser and dropper) is accomplished by sending a different kind of packet.  A firing packet can specify which slot from which to draw the ammunition.  In addition to creating that machine, I wrote up the Technical Manual articles for all existing Eethur machines and fixed some bugs.  Soon, I want to absorb a lot of copy-pasted functionality of my tile entities into some HPTileEntity superclass.

Monday, August 12, 2013

HigherPower - Data Repeater & YouTube Dev Log

I didn't really do much with HigherPower today, but I did add a new data block, the Data Repeater.  Since I'm just using the call stack to transmit packets along a wire, it's entirely possible for a StackOverflowError to halt transmission.  To make exceedingly long lengths of data cable possible, I made the Data Repeater queue up all received packets for transmission on the next tick.  Because the data is not transmitted on the same stack that it is received, the call stack is reset.

Also, I started a small YouTube series in which I will document HigherPower from a developer's perspective.  I just uploaded the first episode, "Slightly Broken", today.  This series will also help me find and fix bugs!

Sunday, August 11, 2013

HigherPower - Damage Counter

In addition to doing some mundane tweaks to Noir generation, I added a new item to HigherPower.  This item is the Damage Counter, a card that keeps track of how much damage the holding player receives and deals.  It works by catching Forge's LivingHurtEvent, checking to see if the holder (or holder's attacker) is a player, looking for a Damage Counter in the player's inventory, and adding the base damage.  The DC does not take into account armor, potions, or other mods' interference in the damage process.  The DC is crafted with some redstone, an iron ingot, some Fleexium, and a tiny bit of Eethur.  Originally, I was using reflection to access the protected entityDamageSource field, but then I discovered the public getter getSourceOfDamage.

Friday, August 9, 2013

HigherPower - Back in Business!

I suddenly got the urge to do some more work on HigherPower, my Minecraft mod.  Since Minecraft updated, Forge also has a new version that of course breaks everything.  The most common issues were that instances of EntityLiving are replaced with the new EntityLivingBase and that the name of "isStackValid" changed to "isItemValid."  The technical name of glowstone dust finally became "glowstone" and the texture binding function got reverted to one of the confusing SRG names.  They did make a very nice change though: dimension IDs are now more easily accessible between mods, so my machines will work in the Twilight Forest and Mystcraft worlds.  To be honest, I don't recall what I was working on before I took this hiatus, but I think I should work on adding more block sensors or that sonic piston idea.