Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devs: objects/UUID compare problems (inner rollbacks problem) #4407

Open
JayDi85 opened this issue Jan 13, 2018 · 12 comments
Open

Devs: objects/UUID compare problems (inner rollbacks problem) #4407

JayDi85 opened this issue Jan 13, 2018 · 12 comments
Labels
bug Bugs and errors refactoring Developers topics about code and programming

Comments

@JayDi85
Copy link
Member

JayDi85 commented Jan 13, 2018

Continue from #4402

You can't compare UUID or objects by == operand. Need to use only obj.equals().

IntelliJ IDEA have inspections on that problems (use custom inspect settings to filter only needed data):
shot_180113_143953

Current project have 72 warnings with == on objects (exported list to web page here):
shot_180113_152710

BUT some xmage objects do not overrides Equals method and use default one, e.g. compare objects by == (compare refs, not data) .

As example, Player objects do not have Equals. All players data searched from game's state object:
shot_180113_151814

But game state can be changed and reverted. In particular, it's saved to history every step by COPY (e.g. new state's players is not equals to old one). And on rollback step can broke something if you save ref object to somewhere (is that can cause of "buggy rollback" function?) or if you have another thread (is xmage use one thread per game?):
shot_180113_152232

I don't known confirmed bug with that issue like with static filters (#4402). But devs have to be careful about this.

Howto fix that:

  • Enable IDE warnings, find and replace == to equals for xmage and UUID objects compare;
  • Add to each needed object overrided equals method. Example for PlayerImp.java (players with same ID will be equal):
@Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        PlayerImpl obj = (PlayerImpl) o;
        if (this.getId() == null || obj.getId() == null) {
            return false;
        }

        return this.getId().equals(obj.getId());
    }
@JayDi85 JayDi85 added bug Bugs and errors refactoring Developers topics about code and programming labels Jan 13, 2018
@LevelX2
Copy link
Contributor

LevelX2 commented Jan 13, 2018

Good findings! 👍

@ingmargoudt
Copy link
Contributor

ingmargoudt commented Jan 13, 2018

Very good finding!!

A use the project Lombok jar often, which is a library that creates constructors, getters, setters and equal methods automatically for you with just an annotation

@Zzooouhh
Copy link
Contributor

Interesting, does it impact OneShotEffects too (since they're presumably reverted along with the rollback), or is only a problem for continuous effects in practice?

@JayDi85
Copy link
Member Author

JayDi85 commented Jan 13, 2018

Restore/rollback works dangerous. Looked at code. Game save new state every steps (save a copy of current state with all data, triggers, effects, players, cards, etc).

On restore request it search needed state by index and delete all other after that state:

shot_180113_195424

And replace all current state's data with old one. Old triggers copy too -- it's can't get current effects:
shot_180113_200309

If something have ref to old state's data on that point then it will be broken (like another thread or code execute after restore point).

P.S. O_o Found that restore/rollback used in targets process -- if was wrong target then all state restored O_o It's may be very buggy and broke the game even without rollbacks (if that "rollback" doesn't work correct):
shot_180113_201249

And many more places like payOrRollback abilities:
shot_180113_204823

@JayDi85
Copy link
Member Author

JayDi85 commented Jan 13, 2018

@Zzooouhh yes, replacement bugs from restore/rollback function. That's it. It use save state before cast and then restored after cast (e.g. all data checks after restore will be dangerous to use by refs):

shot_180113_201808

shot_180113_201830

@JayDi85
Copy link
Member Author

JayDi85 commented Jan 13, 2018

Another bad thing with restore (I think) -- on wrong ability it's try to restore AND after restore use old objects/ref to old state. But that old state was removed and inaccessible. Something bad may happing here (or may not -- I don't know details of java VM and GC works). That's ok -- UUID are fine between states.

shot_180113_202611

@JayDi85
Copy link
Member Author

JayDi85 commented Jan 13, 2018

As a fast workaround it may be good idea do not remove all old state on restore, but moved it to temp object (e.g. ensure that all old refs will works to the end). Maybe debugger or JVM have feature to find out all refs to that object after it was moved to temp -- that's can help to find wrong code.

shot_180113_195424

@LevelX2
Copy link
Contributor

LevelX2 commented Jan 13, 2018

Normally Players or MageObjects won't be checked directly.
They are compared by their UUID and if equals is used for the ID it works as intended.

So I don't see that bugy anywhere. But indeed we have to replace == checks on the UUIDs with equals.

@LevelX2
Copy link
Contributor

LevelX2 commented Apr 27, 2018

Are all "==" replaced and this can be closed?

@JayDi85
Copy link
Member Author

JayDi85 commented Apr 28, 2018

Well, I've checked and fixed warning from IDE about == problems in c24ba74. It's can be closed. But devs must check static analyser warnings time by time.

@JayDi85 JayDi85 closed this as completed Apr 28, 2018
@JayDi85 JayDi85 changed the title Devs: objects/UUID compare problems Devs: objects/UUID compare problems (inner rollbacks problem) May 5, 2019
@JayDi85
Copy link
Member Author

JayDi85 commented May 5, 2019

Found real life proof (#5784) of that problem:

shot_190506_001520

@JayDi85 JayDi85 reopened this May 5, 2019
@JayDi85
Copy link
Member Author

JayDi85 commented Jun 16, 2019

Another one example of rollback and game state problem (#5835 with buyback ability -- a few bugs have allowed this ability to work):

  • xmage uses copies of spells/abilities to play in many places, not original objects;
    shot_190616_214128
  • some objects can store inner data/statuses;
    shot_190616_213823
  • some objects forget to make copy and uses one object ref in all instances (e.g. same object in all game states -- that's ok for const objects):
    shot_190616_214606
  • some objects can change inner data and that's data can be used outside of that objects:
    shot_190616_215033
    shot_190616_215117
  • that's wrong -- you must use game state to store dynamic and shared data not inner objects:
    shot_190616_215210

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bugs and errors refactoring Developers topics about code and programming
Projects
No open projects
Development

No branches or pull requests

4 participants