Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

Implemented a conditional targeting system for cards. This allows TargetingInfo to include a set of Conditions that evaluate against the game world and the potential target. The TargetingArrow UI component now respects these conditions, preventing the selection and highlighting of invalid targets. Added Condition interface and updated TargetingInfo and GameState to support this logic.


PR created automatically by Jules for task 17706898319591583784 started by @Lunkle

@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@Lunkle
Copy link
Member

Lunkle commented Jan 7, 2026

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a conditional targeting system for cards, which is a valuable addition. The implementation is generally well-done. My review includes suggestions to improve encapsulation and robustness in TargetingInfo by using defensive copying and returning unmodifiable lists. I've also pointed out an opportunity to refactor TargetingArrow to use a more modern, stream-based approach for checking conditions and to address code duplication in the rendering logic. These changes will enhance the code's maintainability and prevent potential bugs.

public TargetingInfo(TargetType targetType, int range, Condition... conditions) {
this.targetType = targetType;
this.range = range;
this.conditions = Arrays.asList(conditions);

Choose a reason for hiding this comment

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

high

Using Arrays.asList() creates a list that is a view of the original array. If the caller modifies the conditions array after calling this constructor, it will also modify the list within this TargetingInfo instance. This can lead to unexpected behavior and subtle bugs. To ensure the TargetingInfo object is immutable with respect to its conditions, you should create a defensive copy.

Suggested change
this.conditions = Arrays.asList(conditions);
this.conditions = new java.util.ArrayList<>(Arrays.asList(conditions));

}

public List<Condition> conditions() {
return conditions;

Choose a reason for hiding this comment

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

medium

Returning the internal list directly allows client code to modify it (if it's mutable), which breaks encapsulation. It's a good practice to return an unmodifiable view of the list to protect the internal state of the object. This is especially important if you change the constructor to create a mutable ArrayList as suggested in another comment.

Suggested change
return conditions;
return java.util.Collections.unmodifiableList(conditions);

if (info.targetType() == TargetType.HEXAGON) {
target = tile;
if (target == null) {
if (target == null || !checkConditions(info, state.world(), target)) {

Choose a reason for hiding this comment

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

medium

There is significant code duplication between this block for TargetType.HEXAGON and the one for TargetType.CARD_PLAYER on lines 65-81. The logic for rendering the target highlight is identical. Consider extracting this duplicated code into a private helper method to improve maintainability. The only difference is how the target is determined (tile vs tile.actor()).

Comment on lines 112 to 119
private boolean checkConditions(TargetingInfo info, nomadrealms.context.game.world.World world, Target target) {
for (Condition condition : info.conditions()) {
if (!condition.test(world, target)) {
return false;
}
}
return true;
}

Choose a reason for hiding this comment

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

medium

This method can be written more concisely using Java Streams. Additionally, it's better to import nomadrealms.context.game.world.World and use its simple name World in the method signature for improved readability.

After adding import nomadrealms.context.game.world.World; at the top of the file, you can simplify this method as suggested.

	private boolean checkConditions(TargetingInfo info, World world, Target target) {
		return info.conditions().stream().allMatch(c -> c.test(world, target));
	}

@Lunkle Lunkle force-pushed the card-targeting-conditions-17706898319591583784 branch from 3000dcd to ae95473 Compare January 10, 2026 01:32
- Create `Condition` interface for target validation
- Update `TargetingInfo` to accept a list of conditions (via varargs)
- Expose `world()` in `GameState`
- Update `TargetingArrow` to check conditions before highlighting a target
@Lunkle Lunkle force-pushed the card-targeting-conditions-17706898319591583784 branch from ae95473 to f0ced5a Compare January 10, 2026 01:55
@Lunkle Lunkle marked this pull request as ready for review January 10, 2026 14:15
@Lunkle Lunkle merged commit a6df20a into main Jan 10, 2026
1 check passed
@Lunkle Lunkle deleted the card-targeting-conditions-17706898319591583784 branch January 10, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants