This is a fantastic tutorial - couldn't have written it better myself. Actually, knowing my documenting skills, it would most definitely have been worse *ha-ha*
It looks like you might have multiple bars rendering over each other, or perhaps your texture is not the correct resolution. What I would do, if I were you, is try to just get a simple, solid bar to render first, without doing any of your stamina calculations - comment all that stuff out.
Another possibility is you may need to set the color before you render: GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
This way the color that you see in your texture file is the color that will render on the screen, as many of the Minecraft render functions change the openGL color settings.
The png file staminaBar is the picture attached earlier. 82p x 30p each bar 82p x 5x. I looked into that earlier too.
I've already commented all of the rendering code out accept the background bar, if anything changes at all the bar, became blacker. I say this because I remember seeing it as a shade of blue at some test. I don't remember which. I tested so many times with similar results.
EDIT: Black and gray striped
Additionally, currently, I have two GL11 methods being called:
This is a fantastic tutorial - couldn't have written it better myself. Actually, knowing my documenting skills, it would most definitely have been worse *ha-ha*
Excellently done, coolAlias!
Thanks Mithion, I couldn't have done it without you! (literally, since you co-wrote the code for IExtendedEntityProperties XD ). You have contributed way more than I can ever hope to the modding community here. Thanks again for stopping by - it means a lot to me.
The png file staminaBar is the picture attached earlier. 82p x 30p each bar 82p x 5x. I looked into that earlier too.
I've already commented all of the rendering code out accept the background bar, if anything changes at all the bar, became blacker. I say this because I remember seeing it as a shade of blue at some test. I don't remember which. I tested so many times with similar results.
EDIT: Black and gray striped
Additionally, currently, I have two GL11 methods being called:
I planned on adjusting the values for glColor4f to see if it changed the color of my "bar"... Black f'n Box. ...
Changed glColor4f values to 1, 0, 0, 1 turned the pattern shades of red as expected. I don't understand why this isn't working.
That truly is bizarre. Which RenderGameOverlayEvent ElementType are you rendering your stamina bar in? Have you tried changing that rendering to happen in a different type? What I mean is: handle the health / hunger bars where you do now, since that works, but make sure you handle your stamina bar in a different type, such as the experience bar element.
If that doesn't work for you, might I suggest posting a topic in the "Modification Development" section dedicated to your issue? There is not much more I can offer you since I have pretty limited knowledge of openGL and rendering in general, and the people who may be able to help you probably aren't frequenting this particular thread with any regularity if at all. You are much more likely to get the help you need if you create a new topic. Sorry I couldn't be of much help!
The Meaning of Life, the Universe, and Everything.
Join Date:
7/2/2014
Posts:
55
Minecraft:
BinaryAura
Member Details
BossHealth, so it should come where they normally do, and my bar between BossHealth and Health. I don't believe that it would help any to be honest. I've messed around with the openGL methods trying to get something to happen. As I understand it most of the methods terminate whatever change they made to the openGL at the end of their render methods. The only exception to this isn't even openGL, it's the bind(). I'll link you to my git for this. Maybe reviewing this would help.
I apologize for 1. The lack of comments in my classes. and 2. The lack of descriptions for the classes in git- I haven't figured out how to do that yet. I'll work on this in time.
Thanks for the tutorial. Most of my code was based on your code. It's odd how it's behaving. Thanks for the attention you've given to my issue.
The Meaning of Life, the Universe, and Everything.
Join Date:
7/2/2014
Posts:
55
Minecraft:
BinaryAura
Member Details
Hey, coolAlias, is there a way to have the EntityClientPlayerMP Minecraft.thePlayer refer to the same ExtendedProperties as the EntityPlayerMP version?
get(You (server)) -------> different ExtendedPlayer
EDIT: After thinking about this, this doesn't really make sense the server version isn't necessarily on the client computer.
I'm trying to use commands to update the a boolean variable in my StaminaPlayer class but, when I call it my output goes back and forth between the two. I suspect that one is the client mc.thePlayer and the other is the server version of the "same" player. How do I make this work?
Should events be registering twice? When I print a counter for how many times my player jumps, it shows 1-1, 2-2, 3-3, etc. Then when I leave and rejoin the world, it says 1-4, 2-5, 3-6, etc., as if the client and server are printing their own separate versions of the counter. I'm using forge-1.7.2-10.12.2.1121.
Should events be registering twice? When I print a counter for how many times my player jumps, it shows 1-1, 2-2, 3-3, etc. Then when I leave and rejoin the world, it says 1-4, 2-5, 3-6, etc., as if the client and server are printing their own separate versions of the counter. I'm using forge-1.7.2-10.12.2.1121.
When you run the game both the client instance (EntityClientPlayerMP mc.thePlayer) and the server instance (EntityPlayerMP) both register.
Exactly as Binary_Aura stated, which is also the reason that you should ONLY calculate things on the server, and send the correct amounts to the client as needed, unless there is absolutely no consequence to the data being different, but the only cases I can think of where that is the case are ones in which the calculations are all done exclusively on the client side, e.g. the exact locations of each particle spawned in a randomized cloud.
I have a problem, probably something really simple...
WorldTickEvent is firing three times on Phase.END and I have no idea why.
@SubscribeEvent
public void onTick(WorldTickEvent event) {
if(!event.world.isRemote && event.phase == Phase.END) {
//if(event.side == Side.SERVER && event.phase == Phase.END) {
Long thisTick = event.world.getWorldTime();
if (thisTick % 100L == 0) {
// tick count prints to console 3 times in a row every 100 ticks
System.out.println(thisTick.toString());
}
I have the event registered in my CommonProxy init. I've tried both event.side and the isRemote, no change.
I only want this to happen on the server side, it will be handling world-related data. Not quite got my grips on this proxy stuff obviously.
EDIT: I've verified that the event is only being registered once via it's constructor incase I did something wrong.
EDIT2: If I change it to Side.CLIENT it's not fired at *all*, is this more nonsense about 'server' events not happening in the integrated server again? Even if I move the registration to ClientProxy the Side.CLIENT still won't fire, if I remove it completely and check only the Phase then it's the same 3x console output. I've spent like an hour on this before asking anyone lol
Forge events are not related to proxies, though the client proxy is useful for registering event handlers for events that only fire on the client. Is your 'onTick' method located in its own class, or did you actually put the whole method in the CommonProxy?
Anyway, I haven't really been able to track down what could be the cause; WorldTickEvent is posted from the FMLCommonHandler onPre/PostWorldTick methods, and the only place I was able to find those methods being called is in the WorldServer#updateTimeLightAndEntities method.
I suppose it is possible that this method may be called up to three times per nanosecond... but that would be pretty surprising. Is the value for 'thisTick' the same all three times in a row?
If you want a tick only on the server, a sure way to do so is by using the ServerTickEvent, though I don't think that gives you a World object :\
Forge events are not related to proxies, though the client proxy is useful for registering event handlers for events that only fire on the client.
In the case of WorldTickEvent though which fires on both client and server, it makes sense to only check client/server to prevent a double-fire right? Or do you just mean that they can be registered in/out a proxy and it doesn't matter, but that a sided check within the event method is the only way? I am using @SubscribeEvent @SideOnly(Side.SERVER) somewhere else, is that not good practice?
Is your 'onTick' method located in its own class, or did you actually put the whole method in the CommonProxy?
New class via FMLCommonHandler on postInit in CommonProxy (via proxy.postInit in main class)
Anyway, I haven't really been able to track down what could be the cause; WorldTickEvent is posted from the FMLCommonHandler onPre/PostWorldTick methods, and the only place I was able to find those methods being called is in the WorldServer#updateTimeLightAndEntities method.
I suppose it is possible that this method may be called up to three times per nanosecond... but that would be pretty surprising. Is the value for 'thisTick' the same all three times in a row?
Ha really? Would it be bad (performance wise) if I set global tickDone = thisTick after running on thisTick, and just check that before running (so it only runs once) if that makes sense? I plan to do a *lot* of work with ticks to simulate "random happenings" in the mod so yeah.
If you want a tick only on the server, a sure way to do so is by using the ServerTickEvent, though I don't think that gives you a World object :\
Yeah tried that, nope... tried to get it from Minecraft instance and it'd always crash (not possible I'm guessing?)
I tried registering on WorldEvent.Load but that EVENT_BUS was registered like four times, is that due to the several broadcasts as outlined in JavaDocs?
Sorry for the many questions, I'm determined to understand the inner workings best I can to improve future endevours. You're too helpful
The Meaning of Life, the Universe, and Everything.
Join Date:
7/2/2014
Posts:
55
Minecraft:
BinaryAura
Member Details
I'm trying to run my mod as a server so the difference between client and server becomes apparent. How do you set up the GUI code to not run under a server?
In the case of WorldTickEvent though which fires on both client and server, it makes sense to only check client/server to prevent a double-fire right? Or do you just mean that they can be registered in/out a proxy and it doesn't matter, but that a sided check within the event method is the only way? I am using @SubscribeEvent @SideOnly(Side.SERVER) somewhere else, is that not good practice?
New class via FMLCommonHandler on postInit in CommonProxy (via proxy.postInit in main class)
Ha really? Would it be bad (performance wise) if I set global tickDone = thisTick after running on thisTick, and just check that before running (so it only runs once) if that makes sense? I plan to do a *lot* of work with ticks to simulate "random happenings" in the mod so yeah.
Yeah tried that, nope... tried to get it from Minecraft instance and it'd always crash (not possible I'm guessing?)
I tried registering on WorldEvent.Load but that EVENT_BUS was registered like four times, is that due to the several broadcasts as outlined in JavaDocs?
Sorry for the many questions, I'm determined to understand the inner workings best I can to improve future endevours. You're too helpful
Ok, here we go:
1. NEVER use @SideOnly, especially for Side.SERVER - it was never intended for use by modders, only for FML internally.
2. NEVER use Minecraft.getMinecraft() - it is CLIENT side only, which means it does not exist at all on the server, so of course it didn't work for you when you tried to use it on the server. You can actually use it when you are on the client, but it's best if you avoid it whenever possible, simply so you don't accidentally place one in a server method and crash your game when run outside of single player.
3. Using 'if (side == Side.SERVER)' or 'if (!world.isRemote)' are both valid ways to restrict a section of code to running only on the server, provided that the section of code is at least called on the server in the first place.
4. WorldEvents happen per dimension, though I don't think that should cause it to be posted four times during testing; I did not find any Java docs for that class (using Forge 1121). What do you mean you 'tried registering' on WorldEvent.Load?
5. You can use 'FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]' to get a WorldServer object (which extends World, so can be used just like a World object). This can be used anywhere on the server when you don't have a world instance, though I'm not sure what happens when you get several dimensions loaded at once, i.e. is there a new WorldServer added to the array for each dimension, or is there only ever one? I have never used it, so I have no idea :\
I will have to find some time to play around with the WorldTickEvent and see what's going on there. I would recommend just throwing in as many println statements as you can to track down what's going on:
Something like that will completely spam your console, but it will give you a very good idea of exactly what is going on after running for just a few seconds. If you wanted to see the results of your division, you could also add in a second println("Time % 100L = " + event.world.getWorldTime() % 100L).
I'm trying to run my mod as a server so the difference between client and server becomes apparent. How do you set up the GUI code to not run under a server?
How would your Gui code possibly be trying to run on the server? Please see the tutorial - I cover creating a Gui in there.
If you had read the tutorial, you would know why it crashed (referencing client-side only class on the server) and where to register it so it won't crash (ClientProxy). Please take the time to read the full tutorial.
The Meaning of Life, the Universe, and Everything.
Join Date:
7/2/2014
Posts:
55
Minecraft:
BinaryAura
Member Details
I did, I missed where to register it, anyway, I'm still confused though. Is the field proxy supposed to be of CommonProxy or ClientProxy. And if it's of CommonProxy, how would the ClientProxy's registerRenderer's ever be called?
The question above is now How. I have a problem with:
Ok thanks coolAlias - so never use @Side or getMinecraft, I do remember reading you/someone say that before but I sure see them a lot! Only getMinecraftServerInstance is safe, got it.
EDIT2: Nevermind about the WorldEvent stuff, it makes perfect sense. Server fires it three times - one for each vanilla dimension, and then once on the client side for the current player dimension.
...and that's also why I get each world tick three times, one for each dimension solved!
Thanks for the valuable tips yet again.
@Binary_Aura I'm guessing CommandStamina is a class that draws a GUI? Register a class that checks for the client side first instead.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumExcellently done, coolAlias!
The png file staminaBar is the picture attached earlier. 82p x 30p each bar 82p x 5x. I looked into that earlier too.
I've already commented all of the rendering code out accept the background bar,
if anything changes at all the bar, became blacker. I say this because I remember seeing it as a shade of blue at some test. I don't remember which. I tested so many times with similar results.EDIT: Black and gray striped
Additionally, currently, I have two GL11 methods being called:
I planned on adjusting the values for glColor4f to see if it changed the color of my "bar"... Black f'n Box. ...
Changed glColor4f values to 1, 0, 0, 1 turned the pattern shades of red as expected. I don't understand why this isn't working.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThanks Mithion, I couldn't have done it without you! (literally, since you co-wrote the code for IExtendedEntityProperties XD ). You have contributed way more than I can ever hope to the modding community here. Thanks again for stopping by - it means a lot to me.
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumThat truly is bizarre. Which RenderGameOverlayEvent ElementType are you rendering your stamina bar in? Have you tried changing that rendering to happen in a different type? What I mean is: handle the health / hunger bars where you do now, since that works, but make sure you handle your stamina bar in a different type, such as the experience bar element.
If that doesn't work for you, might I suggest posting a topic in the "Modification Development" section dedicated to your issue? There is not much more I can offer you since I have pretty limited knowledge of openGL and rendering in general, and the people who may be able to help you probably aren't frequenting this particular thread with any regularity if at all. You are much more likely to get the help you need if you create a new topic. Sorry I couldn't be of much help!
https://github.com/jadunker/StaminaMod
I apologize for 1. The lack of comments in my classes. and 2. The lack of descriptions for the classes in git- I haven't figured out how to do that yet. I'll work on this in time.
Thanks for the tutorial. Most of my code was based on your code. It's odd how it's behaving. Thanks for the attention you've given to my issue.
get(You (client)) ----> ExtendedPlayer <---- get(You (server))
instead of
get(You (client)) -----> ExtendedPlayer
get(You (server)) -------> different ExtendedPlayer
EDIT: After thinking about this, this doesn't really make sense the server version isn't necessarily on the client computer.
I'm trying to use commands to update the a boolean variable in my StaminaPlayer class but, when I call it my output goes back and forth between the two. I suspect that one is the client mc.thePlayer and the other is the server version of the "same" player. How do I make this work?
-
View User Profile
-
View Posts
-
Send Message
Curse Premium-
View User Profile
-
View Posts
-
Send Message
Curse PremiumExactly as Binary_Aura stated, which is also the reason that you should ONLY calculate things on the server, and send the correct amounts to the client as needed, unless there is absolutely no consequence to the data being different, but the only cases I can think of where that is the case are ones in which the calculations are all done exclusively on the client side, e.g. the exact locations of each particle spawned in a randomized cloud.
WorldTickEvent is firing three times on Phase.END and I have no idea why.
@SubscribeEvent public void onTick(WorldTickEvent event) { if(!event.world.isRemote && event.phase == Phase.END) { //if(event.side == Side.SERVER && event.phase == Phase.END) { Long thisTick = event.world.getWorldTime(); if (thisTick % 100L == 0) { // tick count prints to console 3 times in a row every 100 ticks System.out.println(thisTick.toString()); }I have the event registered in my CommonProxy init. I've tried both event.side and the isRemote, no change.
I only want this to happen on the server side, it will be handling world-related data. Not quite got my grips on this proxy stuff obviously.
EDIT: I've verified that the event is only being registered once via it's constructor incase I did something wrong.
EDIT2: If I change it to Side.CLIENT it's not fired at *all*, is this more nonsense about 'server' events not happening in the integrated server again? Even if I move the registration to ClientProxy the Side.CLIENT still won't fire, if I remove it completely and check only the Phase then it's the same 3x console output. I've spent like an hour on this before asking anyone lol
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumAnyway, I haven't really been able to track down what could be the cause; WorldTickEvent is posted from the FMLCommonHandler onPre/PostWorldTick methods, and the only place I was able to find those methods being called is in the WorldServer#updateTimeLightAndEntities method.
I suppose it is possible that this method may be called up to three times per nanosecond... but that would be pretty surprising. Is the value for 'thisTick' the same all three times in a row?
If you want a tick only on the server, a sure way to do so is by using the ServerTickEvent, though I don't think that gives you a World object :\
In the case of WorldTickEvent though which fires on both client and server, it makes sense to only check client/server to prevent a double-fire right? Or do you just mean that they can be registered in/out a proxy and it doesn't matter, but that a sided check within the event method is the only way? I am using @SubscribeEvent @SideOnly(Side.SERVER) somewhere else, is that not good practice?
New class via FMLCommonHandler on postInit in CommonProxy (via proxy.postInit in main class)
Ha really? Would it be bad (performance wise) if I set global tickDone = thisTick after running on thisTick, and just check that before running (so it only runs once) if that makes sense? I plan to do a *lot* of work with ticks to simulate "random happenings" in the mod so yeah.
Yeah tried that, nope... tried to get it from Minecraft instance and it'd always crash (not possible I'm guessing?)
I tried registering on WorldEvent.Load but that EVENT_BUS was registered like four times, is that due to the several broadcasts as outlined in JavaDocs?
Sorry for the many questions, I'm determined to understand the inner workings best I can to improve future endevours. You're too helpful
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumOk, here we go:
1. NEVER use @SideOnly, especially for Side.SERVER - it was never intended for use by modders, only for FML internally.
2. NEVER use Minecraft.getMinecraft() - it is CLIENT side only, which means it does not exist at all on the server, so of course it didn't work for you when you tried to use it on the server. You can actually use it when you are on the client, but it's best if you avoid it whenever possible, simply so you don't accidentally place one in a server method and crash your game when run outside of single player.
3. Using 'if (side == Side.SERVER)' or 'if (!world.isRemote)' are both valid ways to restrict a section of code to running only on the server, provided that the section of code is at least called on the server in the first place.
4. WorldEvents happen per dimension, though I don't think that should cause it to be posted four times during testing; I did not find any Java docs for that class (using Forge 1121). What do you mean you 'tried registering' on WorldEvent.Load?
5. You can use 'FMLCommonHandler.instance().getMinecraftServerInstance().worldServers[0]' to get a WorldServer object (which extends World, so can be used just like a World object). This can be used anywhere on the server when you don't have a world instance, though I'm not sure what happens when you get several dimensions loaded at once, i.e. is there a new WorldServer added to the array for each dimension, or is there only ever one? I have never used it, so I have no idea :\
I will have to find some time to play around with the WorldTickEvent and see what's going on there. I would recommend just throwing in as many println statements as you can to track down what's going on:
public void onWorldTick(WorldTickEvent event) { System.out.printf("Is client: %s | Side: %s | Phase: %s | World Time: %s | System Time: %s", event.world.isRemote, (event.side == Side.SERVER ? "SERVER" : "CLIENT"), (event.phase == Phase.END ? "END" : "START"), event.world.getWorldTime(), System.nanoTime()); }Something like that will completely spam your console, but it will give you a very good idea of exactly what is going on after running for just a few seconds. If you wanted to see the results of your division, you could also add in a second println("Time % 100L = " + event.world.getWorldTime() % 100L).
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumHow would your Gui code possibly be trying to run on the server? Please see the tutorial - I cover creating a Gui in there.
in my main file:
-
View User Profile
-
View Posts
-
Send Message
Curse PremiumIf you had read the tutorial, you would know why it crashed (referencing client-side only class on the server) and where to register it so it won't crash (ClientProxy). Please take the time to read the full tutorial.
I'm still confused though. Is the field proxy supposed to be of CommonProxy or ClientProxy. And if it's of CommonProxy, how would the ClientProxy's registerRenderer's ever be called?The question above is now How. I have a problem with:
under a method requiring FMLServerStaringEvent in my main file
EDIT2: Nevermind about the WorldEvent stuff, it makes perfect sense. Server fires it three times - one for each vanilla dimension, and then once on the client side for the current player dimension.
...and that's also why I get each world tick three times, one for each dimension
Thanks for the valuable tips yet again.
@Binary_Aura I'm guessing CommandStamina is a class that draws a GUI? Register a class that checks for the client side first instead.