Fractal Softworks Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Starsector 0.97a is out! (02/02/24); New blog post: Simulator Enhancements (03/13/24)

Author Topic: [Bug(?)/Unintended Code Behaviour] Reality breakage 101  (Read 1132 times)

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
[Bug(?)/Unintended Code Behaviour] Reality breakage 101
« on: June 16, 2019, 01:08:54 AM »

(While coming up with the title, I wished I managed to get some better footage of the actual results of this behaviour, but it seems it doesn't break much in vanilla. However, I felt it needed to be pointed out anyhow)

After some confusing tours in my code where things seemed to break seemingly at random in scripts I had no control over (including other mods!) I finally found what was causing these oddities: Misc.ZERO, the zero-vector constant defined in the Misc package, is not actually a true constant. It cannot be "set", and the object reference is indeed constant. However, there are ways to affect it:
Code: java
Misc.ZERO = new Vector2f(9000f, 0f); /* This, as intended, does not work and will throw an error */
Misc.ZERO.x += 9000f; /* This WORKS, and makes all vector math that happens to use Misc.ZERO completely break down */
While this behaviour causes no issues in vanilla, and doesn't happen unless someone happens to overwrite it, it feels like an oversight that might create some strange and hard-to-find buggy behaviour down the line should it be treated as a constant. I know it took me quite the while to figure out the bug, and I only had 7 lines of code to debug!

I'm not sure how possible it is but I think that, from a coding standpoint, Misc.ZERO should probably be set as some form of "true" constant, however this would be achieved in java (alternatively, turned into a function that always returns new Vector2f(0f, 0f)).

Dark.Revenant

  • Admiral
  • *****
  • Posts: 2806
    • View Profile
    • Sc2Mafia
Re: [Bug(?)/Unintended Code Behaviour] Reality breakage 101
« Reply #1 on: June 16, 2019, 02:54:05 AM »

Ah, the good 'ol myth of const.
Logged

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23986
    • View Profile
Re: [Bug(?)/Unintended Code Behaviour] Reality breakage 101
« Reply #2 on: June 16, 2019, 03:22:02 PM »

Yeah, this is very much a "how java works" situation.  (Or how programming works, more or less...) There's no way to do what you're suggesting, and returning a new vector every time is the thing that having the ZERO vector be pre-defined is avoiding, although the performance benefits of this in Java 7 are minimal if not non-existent; it was more of a thing earlier. But it's still a tad bit more convenient.

Just, well, don't change it! Generally speaking, any static should be changed only if you know exactly what you're doing. I do get that you apparently did this unintentionally, but... that's probably a good practical example of working with references, and needing to be very much aware of them :) This is *far* from the only situation where doing this sort of thing could bite you.
Logged

Nicke535

  • Commander
  • ***
  • Posts: 240
  • Degenerate Core
    • View Profile
Re: [Bug(?)/Unintended Code Behaviour] Reality breakage 101
« Reply #3 on: June 16, 2019, 11:11:17 PM »

Fair enough. Always thought it was a short-hand term rather than a performance saver. Just assumed it acted like "true" constants, somehow (being in all-caps and everything); guess there isn't really a way to create a true constant Java object, only a primitive constant.

Alex

  • Administrator
  • Admiral
  • *****
  • Posts: 23986
    • View Profile
Re: [Bug(?)/Unintended Code Behaviour] Reality breakage 101
« Reply #4 on: June 18, 2019, 07:28:01 AM »

Right, yeah. Well, sort of. "final" is acting exactly the same in both cases - it's preventing the variable from being changed. In this case, the variable is a reference to an object, whose fields are not final. Which it sounds like you understand, from what you're saying; so, right, no magic here, just final doing what final does.

You could also change a "true" primitive constant using reflection, which is the sort of thing Dark.Revenant is referring to with his comment :)

(I will say that I rather dislike using final for variables, even ones that are intended to be constants. The ZERO vector is a rare example where it would actually be appropriate, but in most cases... the convenience of being able to change it - either by a mod, or using hot code replacement without having to restart the game while developing - seems worth the risk of this introducing an occasional bug. Which can indeed happen.)
Logged