In my endless quest to further my knowledge, I have undertaken a project to try to reverse engineer the beam cannon from Embers, in the hopes of being able to re create the beam effect for future projects. However, I've begun getting a crash:
The strange thing is, the error doesn't completely crash the game, it just boots you to the main menu with a fatal error. It seems to have something to do with the packets, but it doesn't isolate the actual problem, and I don't know much about packets, hence this project.
[12:38:48] [Netty Local Client IO #0/ERROR] [FML]: FMLIndexedMessageCodec exception caught
io.netty.handler.codec.DecoderException: java.lang.NullPointerException: Undefined message for discriminator 0 in channel examplemod
Pretty sure that's from trying to use a packet you haven't registered.
Also the super() calls in your packet are redundant because there is no super class!
Also you need to access the main thread for the client, not run the code where you have it for your packet handler. Make sure you follow the docs here. And remove the @SideOnly annotation in your packet handler... that's probably a bad idea to have (and unnecessary).
As of Minecraft 1.8 packets are by default handled on the network thread.
That means that your IMessageHandler can not interact with most game objects directly. The example above for example would not be correct. Minecraft provides a convenient way to make your code execute on the main thread instead using IThreadListener.addScheduledTask.
The way to obtain an IThreadListener is using either the Minecraft instance (client side) or a WorldServer instance (server side).
Can you explain this part to me? I don't really get it, I'd need to see an example.
Can you explain this part to me? I don't really get it, I'd need to see an example.
In your packet handler, you need to get the IThreadListener for the current side (either the Minecraft or MinecraftServer instance) and call IThreadListener#addScheduledTask with a Runnable implementation (e.g. a lambda or anonymous class) that actually does whatever the packet handler is meant to do. This Runnable will be called on the main thread, where it's safe to interact with normal Minecraft classes.
You can get the MinecraftServer instance through MessageContext#getServerHandler, NetHandlerPlayServer#player and EntityPlayerMP#mcServer.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
Oh, I see, I was confused about how to create the thread listener, I didn't know that was an object. Anyways, now it gives this error when I use the item, I think the packet is somehow being incorrectly registered.
Every IMessage implementation must have a zero-argument constructor so FML can create an instance of it on the receiving side.
Only return an IMessage from IMessageHandler#onMessage if you want it sent to the other side. Return null if you don't need to send anything.
Returning the IMessage argument is almost never what you want to do, since each IMessage implementation is usually designed to be sent to a specific side. Sending an IMessage to the wrong side won't do anything useful.
There's very limited use for this return value in modern versions of Minecraft, since the actual processing needs to happen on another thread after the method returns. If you need to send a response packet based on some data in the original packet, you need to send it through your SimpleNetworkWrapper manually.
Rollback Post to RevisionRollBack
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
It seems to work after adding a no arg constructor. I forgot those aren't implied. This is so cool! Now, to figure out exactly how it works so I can recreate it in project pixel dungeon, and maybe my gun mod. Thanks everyone!
In my endless quest to further my knowledge, I have undertaken a project to try to reverse engineer the beam cannon from Embers, in the hopes of being able to re create the beam effect for future projects. However, I've begun getting a crash:
http://pastebin.com/Vx6Ke9tn
The strange thing is, the error doesn't completely crash the game, it just boots you to the main menu with a fatal error. It seems to have something to do with the packets, but it doesn't isolate the actual problem, and I don't know much about packets, hence this project.
Here is the item class:
http://pastebin.com/3LucrxTg
and the packet handler:
http://pastebin.com/bWU9MXiT
and the packet itself:
http://pastebin.com/9x1XHKAN
Please note this project is for educational purposes, and won't ever be actually released as is, as that would probably violate Ember's licence.
My first mod =D
Pretty sure that's from trying to use a packet you haven't registered.
Also the super() calls in your packet are redundant because there is no super class!
Also you need to access the main thread for the client, not run the code where you have it for your packet handler. Make sure you follow the docs here. And remove the @SideOnly annotation in your packet handler... that's probably a bad idea to have (and unnecessary).
Can you explain this part to me? I don't really get it, I'd need to see an example.
My first mod =D
In your packet handler, you need to get the IThreadListener for the current side (either the Minecraft or MinecraftServer instance) and call IThreadListener#addScheduledTask with a Runnable implementation (e.g. a lambda or anonymous class) that actually does whatever the packet handler is meant to do. This Runnable will be called on the main thread, where it's safe to interact with normal Minecraft classes.
You can get the MinecraftServer instance through MessageContext#getServerHandler, NetHandlerPlayServer#player and EntityPlayerMP#mcServer.
I use this proxy method (client implementation, server implementation) to get the IThreadListener from the MessageContext in my packet handlers.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
So if you're accessing the client thread, you need to use Minecraft.getMinecraft().
If you're accessing the server thread, you need to use ctx.getServerHandler().playerEntity.world.
You can see an example of me using these both:
Client packet example
Server packet example
Can you show me an example of how that is implemented?
My first mod =D
Oh, I see, I was confused about how to create the thread listener, I didn't know that was an object. Anyways, now it gives this error when I use the item, I think the packet is somehow being incorrectly registered.
Here's the packet: http://pastebin.com/kSQU0N6W
And the handler: http://pastebin.com/4HN6uKDF
And the main class: http://pastebin.com/54hqJiun
Am I doing this right?
My first mod =D
Every IMessage implementation must have a zero-argument constructor so FML can create an instance of it on the receiving side.
Only return an IMessage from IMessageHandler#onMessage if you want it sent to the other side. Return null if you don't need to send anything.
Returning the IMessage argument is almost never what you want to do, since each IMessage implementation is usually designed to be sent to a specific side. Sending an IMessage to the wrong side won't do anything useful.
There's very limited use for this return value in modern versions of Minecraft, since the actual processing needs to happen on another thread after the method returns. If you need to send a response packet based on some data in the original packet, you need to send it through your SimpleNetworkWrapper manually.
Chisel Facades: For all your decorative pipe-hiding needs.
Please don't PM me to ask for help or to join your mod development team. Asking your question in a public thread preserves it for people who are having the same problem in the future. I'm not interested in developing mods with people.
It seems to work after adding a no arg constructor. I forgot those aren't implied. This is so cool! Now, to figure out exactly how it works so I can recreate it in project pixel dungeon, and maybe my gun mod. Thanks everyone!
My first mod =D