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

Dependency Graphs #6869

Merged
merged 7 commits into from
Jan 28, 2025
Merged

Dependency Graphs #6869

merged 7 commits into from
Jan 28, 2025

Conversation

tool4ever
Copy link
Contributor

@tool4ever tool4ever commented Jan 25, 2025

This implements the algorithm I've outlined in #5642 :)

  • tweaked StaticEffect so it can undo single layers only
  • add test that would fail on master

To handle more cases generateStaticAbilityResult will need additional logic for the other layers.
But just comparing the affected objects should already support quite a lot.

Closes #4680
Closes #1850
Closes #4108
Closes #4841
Closes #6669

@tool4ever tool4ever added enhancement New feature or request Game Mechanics Rules compliance Bringing the engine or cards closer to CR labels Jan 25, 2025
@tool4ever tool4ever marked this pull request as draft January 25, 2025 10:32
@Hanmac
Copy link
Contributor

Hanmac commented Jan 25, 2025

final Comparator<StaticAbility> comp = (a, b) -> ComparisonChain.start()
                .compareTrueFirst(a.isCharacteristicDefining(), b.isCharacteristicDefining())
                .compare(a.getHostCard().getLayerTimestamp(), b.getHostCard().getLayerTimestamp())
                .result();
        staticAbilities.sort(comp);

maybe remove this, and separate them inside the layers loop?

@tool4ever
Copy link
Contributor Author

I think right now I do need them pre-sorted once, so I can always start checking from the earliest

@tool4ever
Copy link
Contributor Author

@Hanmac
we could define the comp as Static class field though
maybe better for performance instead of always creating it each time?

@Hanmac
Copy link
Contributor

Hanmac commented Jan 25, 2025

@Hanmac we could define the comp as Static class field though maybe better for performance instead of always creating it each time?

Look what I meant:
#5642 (comment)

I think filtering the list for CDA first would help

@tool4ever
Copy link
Contributor Author

Feel free and try to tweak it 🤔

I tested the sub-issues and easier ones work now, those have been linked for closing

@Hanmac
Copy link
Contributor

Hanmac commented Jan 25, 2025

@tool4ever should we add more test cases?

@tool4ever
Copy link
Contributor Author

@Hanmac
last test updated to prove loop detection works based on
https://apps.magicjudges.org/forum/topic/11405/

@tool4ever tool4ever marked this pull request as ready for review January 26, 2025 09:56
@tool4ever
Copy link
Contributor Author

Performance seems ok for average AI games:
image

It should be O(n*(n-1)) for the amount of statics. The logic shortcut I added probably helps...

@Hanmac
Copy link
Contributor

Hanmac commented Jan 26, 2025

Performance seems ok for average AI games: image

It should be O(n*(n-1)) for the amount of statics. The logic shortcut I added probably helps...

What does the rest of show? I mean should part is the most used one and should be optimized?

@tool4ever
Copy link
Contributor Author

Here's one from a BO5 4 player game with random decks:
image

We can still expect a lesser improvement if I refactor the players do be handled in their own loop. Just need to do more research if they even need dependency checking, so that's another follow-up which can be handled soon after this survives a few snapshots. 🤞

@Hanmac
Copy link
Contributor

Hanmac commented Jan 26, 2025

with rest i mean, what is above? what code (not related to this MR) takes the most amount of power?

@tool4ever
Copy link
Contributor Author

That's a bit harder to tell recently because the AI timeout stuff creates so many threads.
Aggregating their calls in VisualVM requires some trickery I'm still trying to figure out.

But here's a Top10 of Hotspots:
image

If there's another quick-win I haven't found it this way yet.

@Hanmac
Copy link
Contributor

Hanmac commented Jan 27, 2025

@tool4ever i think you can move the Comperator into a Const if you want

but i still think removing the CDA first from the list and then sorting by timestamp / dependency later separate might be better?

@tool4ever
Copy link
Contributor Author

There's no benefit from multiple sort calls since CDA need timestamp order too and this will also make sure they get applied first anyway.

I'm already skipping them for dependency order right now until a case for it gets supported.

➡️ Comparator extracted and converted to native Java

@Hanmac
Copy link
Contributor

Hanmac commented Jan 27, 2025

i haven't found an example for CDA dependency yet, because they can only affect itself, it needs to be something on the same card, or gained something via copy layers

The Full dependency is only in effect when the TreeTable are replaced with LinkedHashMap
and for that to work correct, we need to update the Pump and Animate effects

@tool4ever
Copy link
Contributor Author

Indeed more work / PR will still remain...

Luckily with such effects:

  • they're immutable so removal can't be caused in this way
  • affect Card.IsRemembered or EffectSource so that's fixed too
  • which only leaves the somewhat rarer third case

But is anything else needed here?
Let's please merge to fix what's already possible and worry about the rest step by step :)

Copy link
Contributor

@Hanmac Hanmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is good for now?

We just need to update the other effects soonish

@tool4ever tool4ever merged commit 1e1fa1a into Card-Forge:master Jan 28, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Game Mechanics Rules compliance Bringing the engine or cards closer to CR
Projects
None yet
2 participants