Jump to content

[1.11/1.10] [SOLVED] Cables don't send energy


Recommended Posts

Posted (edited)

Hi,

 

I've got the problem with my cables that in some cases they do not send energy into machines or even into other cables. (see the pictures below)

 

The source code:

BlockTransfer.java

TileEntityPipeTransferEnergy.java

TileEntityEnergy.java (base class)

machine (java file) 

 

I basically linked the files in the repository here (1.10.2 branch) as I've got no clue anymore what the problem maybe (after gettings problems after problems xD).

(Note: It's the 1.10.2 branch as this branch has currently the most up-to-date code online, thought the code base for 1.11 is the same with the same problems.)

 

Thx in advance.

Bektor

 

EDIT:

I tracked some of the problems down to a visual problem which is now solved. Thus I removed the images which show this problem.

I've further tracked the remaining problem down to the BlockTransfer.java class. The code their is not executed when the World gets reloaded, thus

the list for sending the energy in TileEntityPipeTransferEnergy.java stays emtpy. This means I somehow have to call a similiar code also when the world gets reloaded

or the Game restarted etc., but I'm not quite sure where to call this code (normally I would call it in onBlockAdded, but the description of this method states it is called before the tile entity gets placed).

I also don't want to have another if-check in the update-method from my tile entity, if possible.

 

Then I've also noticed that for some reason the machine (java file) doesn't save the stored energy, but it should store it, as I've overridden the nbt methods to store aditional information, but I am still calling the super methods which save and load the data.

base.png

base_1.png

base_2.png

base_4.png

base_6.png

base_3.png

base_5.png

Edited by Bektor

Developer of Primeval Forest.

Posted

This type of problem is usually very specific to your code and not everyone has time to debug other peoples code. So I suggest you just debug the problem. The way I debug a problem is to add a lot of console statements (either System.out.println() statements or Logger) at all the key points in the code. I usually put one before each if statement and inside the if statement to prove which path of the code gets executed.

 

I'm pretty sure if you just print out the energy transfer values at all the points where they are supposed to change, you'll quickly identify which part isn't changing as expected and then you can narrow in to solve the problem.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
On 18.8.2017 at 10:49 PM, jabelar said:

This type of problem is usually very specific to your code and not everyone has time to debug other peoples code. So I suggest you just debug the problem. The way I debug a problem is to add a lot of console statements (either System.out.println() statements or Logger) at all the key points in the code. I usually put one before each if statement and inside the if statement to prove which path of the code gets executed.

 

I'm pretty sure if you just print out the energy transfer values at all the points where they are supposed to change, you'll quickly identify which part isn't changing as expected and then you can narrow in to solve the problem.

Well, that's what I did before posting this post as I actually run into a lot of problems regarding the energy network, so I debugged the whole code the past few days before posting it a few times.

 

Anyway, after taking a small break, I could track down some of the problems regarding the energy network to a visual problem.

After having this fixed, I've further tracked the problem down to the BlockTransfer.java class. The code their is not executed when the World gets reloaded, thus

the list for sending the energy in TileEntityPipeTransferEnergy.java stays emtpy. This means I somehow have to call a similiar code also when the world gets reloaded

or the Game restarted etc., but I'm not quite sure where to call this code (normally I would call it in onBlockAdded, but the description of this method states it is called before the tile entity gets placed).

I also don't want to have another if-check in the update-method from my tile entity, if possible.

 

Then I've also noticed that for some reason the machine (java file) doesn't save the stored energy, but it should store it, as I've overridden the nbt methods to store aditional information, but I am still calling the super methods which save and load the data.

Developer of Primeval Forest.

Posted

I saw your blocks have TileEntity. I guess you should replace onBlockAdded() in Block classes with onLoad() in corresponding TileEntity class. The onLoad() event will be fired when ever the TileEntity is being initialize, on both server and client side. Placing block, chunk loading can both trigger onLoad()

 

PS: Are you making your own energy system?

My mod: SimElectricity - High Voltages, Electrical Power Transmission & Distribution

https://github.com/RoyalAliceAcademyOfSciences/SimElectricity

Posted
7 hours ago, Rikka0_0 said:

I saw your blocks have TileEntity. I guess you should replace onBlockAdded() in Block classes with onLoad() in corresponding TileEntity class. The onLoad() event will be fired when ever the TileEntity is being initialize, on both server and client side. Placing block, chunk loading can both trigger onLoad()

Hm... interesting.. now I'm getting an StackOverflowError:

Spoiler
Quote

[00:04:25] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.StackOverflowError
    at java.util.zip.Inflater.<init>(Unknown Source) ~[?:1.8.0_144]
    at java.util.zip.Inflater.<init>(Unknown Source) ~[?:1.8.0_144]
    at java.util.zip.InflaterInputStream.<init>(Unknown Source) ~[?:1.8.0_144]
    at net.minecraft.world.chunk.storage.RegionFile.getChunkDataInputStream(RegionFile.java:186) ~[RegionFile.class:?]
    at net.minecraft.world.chunk.storage.RegionFileCache.getChunkInputStream(RegionFileCache.java:72) ~[RegionFileCache.class:?]
    at net.minecraft.world.chunk.storage.AnvilChunkLoader.loadChunk__Async(AnvilChunkLoader.java:98) ~[AnvilChunkLoader.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOProvider.run(ChunkIOProvider.java:68) ~[ChunkIOProvider.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(ChunkIOExecutor.java:92) ~[ChunkIOExecutor.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:122) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:93) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:139) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:355) ~[World.class:?]
    at net.minecraft.world.World.getChunkFromBlockCoords(World.java:347) ~[World.class:?]
    at net.minecraft.world.World.getTileEntity(World.java:2595) ~[World.class:?]
    at minecraftplaye.justanotherenergy.common.tileentities.TileEntityPipeTransferEnergy.onLoad(TileEntityPipeTransferEnergy.java:59) ~[TileEntityPipeTransferEnergy.class:?]
    at net.minecraft.world.chunk.Chunk.addTileEntity(Chunk.java:878) ~[Chunk.class:?]
    at net.minecraft.world.chunk.Chunk.addTileEntity(Chunk.java:855) ~[Chunk.class:?]
    at net.minecraft.world.chunk.storage.AnvilChunkLoader.loadEntities(AnvilChunkLoader.java:519) ~[AnvilChunkLoader.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOProvider.syncCallback(ChunkIOProvider.java:96) ~[ChunkIOProvider.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(ChunkIOExecutor.java:94) ~[ChunkIOExecutor.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:122) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:93) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:139) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:355) ~[World.class:?]
    at net.minecraft.world.World.getChunkFromBlockCoords(World.java:347) ~[World.class:?]
    at net.minecraft.world.World.getTileEntity(World.java:2595) ~[World.class:?]
    at minecraftplaye.justanotherenergy.common.tileentities.TileEntityPipeTransferEnergy.onLoad(TileEntityPipeTransferEnergy.java:59) ~[TileEntityPipeTransferEnergy.class:?]
    at net.minecraft.world.chunk.Chunk.addTileEntity(Chunk.java:878) ~[Chunk.class:?]
    at net.minecraft.world.chunk.Chunk.addTileEntity(Chunk.java:855) ~[Chunk.class:?]
    at net.minecraft.world.chunk.storage.AnvilChunkLoader.loadEntities(AnvilChunkLoader.java:519) ~[AnvilChunkLoader.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOProvider.syncCallback(ChunkIOProvider.java:96) ~[ChunkIOProvider.class:?]
    at net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(ChunkIOExecutor.java:94) ~[ChunkIOExecutor.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:122) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.loadChunk(ChunkProviderServer.java:93) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:139) ~[ChunkProviderServer.class:?]
    at net.minecraft.world.World.getChunkFromChunkCoords(World.java:355) ~[World.class:?]
    at net.minecraft.world.World.getChunkFromBlockCoords(World.java:347) ~[World.class:?]
    at net.minecraft.world.World.getTileEntity(World.java:2595) ~[World.class:?]
    at minecraftplaye.justanotherenergy.common.tileentities.TileEntityPipeTransferEnergy.onLoad(TileEntityPipeTransferEnergy.java:59) ~[TileEntityPipeTransferEnergy.class:?]

 

    @Override
    public void onLoad() {
    	super.onLoad();
    	
    	// this has to be called as the dc list relies on it
    	if(this.connected.isEmpty()) {
    		this.findTransferPipes();
    		this.flag = true;
    	}
    	
    	// fill the dc list with data
    	if(this.direct_connect.isEmpty()) {
    		for(EnumFacing side : EnumSet.allOf(EnumFacing.class)) {
    			if(side == null) continue;
    			
    			BlockPos neighbour = this.getPos().offset(side);
    			TileEntity tile = this.getWorld().getTileEntity(neighbour); // line 59, how can here even be a stackoverflow exception???
    			if(tile == null) continue;
    			
    			if(tile instanceof TileEntityPipeTransferEnergy) {
    				// the transfer pipe itself should also not be in the list
    				continue;
    			} else if(tile instanceof TileEntityEnergy) {
    				// we don't want to have producers in our list
    				if(((TileEntityEnergy) tile).container.getTransferMode() == EnergyTransfer.PRODUCER)
    					continue;
    			}
    			
    			if(this.connected.containsKey(neighbour))
    				continue;
    			
        		// check the facing of the block to make sure which side is connected to us
    			for(EnumFacing face : EnumFacing.VALUES) {
    				BlockPos offset = this.getPos().offset(face);
    				if(offset == neighbour) {
    					
    					if(EnergyUtils.hasCapability(tile, face))
    						this.direct_connect.put(neighbour, face);
    				}
    			}
    			if(!this.direct_connect.containsKey(neighbour)) {
    				if(EnergyUtils.hasCapability(tile, null)) {
    					this.direct_connect.put(neighbour, null);
    					this.flag = true;
    				}
    			}
    		}
    	}
    }

 

But interesting with the onLoad method, didn't even know such a method existed.

 

8 hours ago, Rikka0_0 said:

PS: Are you making your own energy system?

Well, I'm making a mod based around energy using Forge Energy (while also supporting Tesla (in theory the Tesla code works ^^)) to be compatible with as many other mods as possible.

Should be pretty close now to adding all the features in instead of writing tons of background logic and doing research on how x thing works. (Pollution from machines incoming ^^)

Developer of Primeval Forest.

Posted
7 hours ago, Bektor said:

Hm... interesting.. now I'm getting an StackOverflowError:

 

Be aware that onLoad() can be call from both server and client side, I guess your energy system simulation logic is server-only, so if you attempt to access the energy system from client side, you will get a NullPointerException.

 

From what I know, getTileEntity attempts to create an TileEntity if there's no existing one at the given location. OnLoad() is called after the tileEntity is loaded. So calling getTileEntity() in OnLoad() can result in a recursive situation, and eventually cause stack overflow /w\

te.png.11fdecbcde30c7587a160146f28c1af8.png

Call Hierarchy

 

Your code looks like updating the appearance of blocks, I guess a better way to do this is to override getActualState(), in your block class

/w\

getActualState handles blockstates which aren't depended on metadata.

 

Some other useful stuff:

Minecraft Forge event: ChunkWatchEvent.Watch

My mod: SimElectricity - High Voltages, Electrical Power Transmission & Distribution

https://github.com/RoyalAliceAcademyOfSciences/SimElectricity

Posted
4 hours ago, Rikka0_0 said:

I guess your energy system simulation logic is server-only

Yeah, it is mostly server-side only. Thought in onNeighborChange is no check if it is called on server or client side and it works fine there (worldIn.isRemote isn't available there).

4 hours ago, Rikka0_0 said:

From what I know, getTileEntity attempts to create an TileEntity if there's no existing one at the given location

I don't think that is how getTileEntity works as getTileEntity is @Nullable, but I never looked that deep into Minecraft src code.

 

4 hours ago, Rikka0_0 said:

Your code looks like updating the appearance of blocks,

It's not updating the appearance of blocks. It's just adding stuff to a list. The first list, connected, is for all cables which are connected to the transfer tiles and the dc (direct_connect) list is for all machines which are directly connected to the transfer tile.

I'm actually checking if on side XX is a tile entity. When there is a tile entity, does it have the correct capability facing towards us?

I'm also making sure it isn't another transfer tile or a energy producer as the dc list is only for sending energy to machines.

The tiles who are in the dc list also aren't allowed to exist in the connected list.

So nothing with block appearance. I might also be able to have one list for both cases, but as these cases have a priority, so a machine gets energy before all other transfer tiles and as the search mechanics for both lists are different, I rather have it split up into two different lists.

 

 

Developer of Primeval Forest.

Posted
3 hours ago, Bektor said:

I don't think that is how getTileEntity works as getTileEntity is @Nullable, but I never looked that deep into Minecraft src code.

That is exactly how it works in most cases. I remember that there is/was a way to get a read-only access on the client somehow, but I do not remember how exactly it is done. It is marked as nullable because it will return null for blocks that don't have a tile entity like a standart stone block for example, but if a block returns true at Block::hasTileEntity and there is not a tileentity currently in the chunk's tile map MC will create a new one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.