Skip to content

Conversation

oscscull
Copy link
Contributor

@oscscull oscscull commented Jun 26, 2025

Part of #12534

  • Adds Room + Room half card types
  • Adds Room unlock ability
  • Adds Room door unlock triggers
  • Adds Room special functionality (locking halves, unlocking, changing names, changing mana values)
  • Adjusts name predicate handling for Room name handling (Rooms have between 0 and 2 names on the battlefield depending on their state. They have 1 name on the stack as a normal split card does). Allows cards to match these names properly
  • Adds Room game events (Unlock, Fully Unlock)
  • Updates Split card constructor to allow a single type line as with Rooms
  • Adds empty name constant for fully unlocked rooms
  • Updates Permanent to include the door unlock states (that all permanents have) that are relevent when a permanent is or becomes a Room.
  • Updates Zone Handler to properly move Room card parts onto and off of the battlefield.
  • Updated Eerie ability to function properly with Rooms
  • Implemented Bottomless Pool // Locker Room
  • Implemented Surgical Suite // Hospital Room
  • Added Room card tests

TODO in this PR

  • Currently nothing

TODO in later PRs

  • Names still need better handling. The workaround here is a simple extension of the existing workaround for split cards. This is functional for Rooms, but not ideal overall. Cards don't really have multiple names, and there are still cards like Psychic Paper for which this solution is not enough.
  • There are plenty more Rooms to implement. I can't currently see any reason this PR shouldn't be sufficient to make implementing any/all of them fairly simple, but it's possible there will be challenges I haven't foreseen here.
  • Currently Room names and mana values are set using a characteristic defining ability in layer 7. This works in all the cases I've tested, but isn't accurate to the rules. I think they should be a layer 1 ability. Currently, making them a layer 1 ability makes clones like clever impersonator original names overwrite the room name, and thus not work properly (I'm not 100% sure why currently). Moving the ability layer is a 1 line change if this bug is fixed and would be nice to have.
  • Might need another pass for graphics. Currently all the important info is displayed in what seems to me to be a conventional way. But might be nice to have icons. There are other ways to layout the card info that might be more pleasing/intuitive from a design perspective.

Supported Rules:
As far as I am aware, all room specific rules are covered in this PR. The one exception being (as above), that I don't think the name and mana values are set in the right layer. Relevent rule below
709.5. Some split cards are permanent cards with a single shared type line. A shared type line on such an object represents two static abilities that function on the battlefield. These are “As long as this permanent doesn’t have the ‘left half unlocked’ designation, it doesn’t have the name, mana cost, or rules text of this object’s left half” and “As long as this permanent doesn’t have the ‘right half unlocked’ designation, it doesn’t have the name, mana cost, or rules text of this object’s right half.” These abilities, as well as which half of that permanent a characteristic is in, are part of that object’s copiable values.

Testing:
I've added 16 total tests so far.
I've covered all situations I could think of off the top of my head, with some very edge cases. With that said, rooms have a lot of associated rules, so there's potentially some weird cases I haven't anticipated.

Copy link
Member

@JayDi85 JayDi85 left a comment

Choose a reason for hiding this comment

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

Code style looks good, but it can be fully reviewed after unit tests added to make sure it's support all rule parts (the most important part -- copy and zone changing logic, also name searching/compare).


// controlling player can be replaced so use event player now
Permanent permanent;
if (card instanceof MeldCard) {
Copy link
Member

Choose a reason for hiding this comment

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

Meld cards are badly tested by unit tests, so it's better to write room related tests for blinks, hand/stack/battlefield copy, etc.

@JayDi85 JayDi85 requested review from theelk801 June 26, 2025 17:06
} else if (card instanceof SplitCard) {
// fused spells allowed (it uses main card)
if (card.getSpellAbility() != null && !card.getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)) {
if (card.getSpellAbility() != null && !card.getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED) && !(card instanceof RoomCard)) {
Copy link
Member

Choose a reason for hiding this comment

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

Make sure all places with SPLIT_FUSED usage checked, same for SPLIT_LEFT and SPLIT_RIGHT:
shot_250626_212008

@Grath
Copy link
Contributor

Grath commented Jun 26, 2025

Edge case for room names which I do not believe is handled by the current hacky workaround for name:

  • Play a room with one side unlocked
  • Play [[Opalescence]] to turn it into a creature
  • Give it a non-mana activated ability (such as [[Diviner's Wand]]'s {4}: Draw a Card)
  • [[Pithing Needle]] the name of the locked side (may or may not be possible as currently coded?)
  • Validate that the room can still activate the gained ability
  • Unlock the other side, so it gains the name of the other side
  • Validate that you can no longer activate the ability.

Copy link

Opalescence - (Gatherer) (Scryfall) (EDHREC)

{2}{W}{W}
Enchantment
Each other non-Aura enchantment is a creature in addition to its other types and has base power and base toughness each equal to its mana value.

Diviner's Wand - (Gatherer) (Scryfall) (EDHREC)

{3}
Kindred Artifact — Wizard Equipment
Equipped creature has "Whenever you draw a card, this creature gets +1/+1 and gains flying until end of turn" and "{4}: Draw a card."
Whenever a Wizard creature enters, you may attach this Equipment to it.
Equip {3}

Pithing Needle - (Gatherer) (Scryfall) (EDHREC)

{1}
Artifact
As this artifact enters, choose a card name.
Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.

@Grath
Copy link
Contributor

Grath commented Jun 26, 2025

(Also speaking of Opalescence - make sure that the mana value of the room reflects the mana value of the unlocked sides; a non-cast Room should have zero mana value and die with Opalesence in play, a half-unlocked room should have the mana value of that unlocked side, and a fully unlocked room should have the total mana value.)

@JayDi85
Copy link
Member

JayDi85 commented Jun 27, 2025

Also check other room cards — some of it can contain unique logic and can require additional changes to support it.

@oscscull
Copy link
Contributor Author

oscscull commented Jul 3, 2025

Edge case for room names which I do not believe is handled by the current hacky workaround for name:

  • Play a room with one side unlocked
  • Play [[Opalescence]] to turn it into a creature
  • Give it a non-mana activated ability (such as [[Diviner's Wand]]'s {4}: Draw a Card)
  • [[Pithing Needle]] the name of the locked side (may or may not be possible as currently coded?)
  • Validate that the room can still activate the gained ability
  • Unlock the other side, so it gains the name of the other side
  • Validate that you can no longer activate the ability.

I will check these specifically. I have done a lot of changes to the code with opalescence + bile blight for local testing so that works for sure. Also testing mirage mirror and similar copy effects have a lot of edge cases. I asked the judge reddit for what happens when a room loses all its abilities + opalescence + muraganda petroglyphs but, got no definite answer.

@oscscull
Copy link
Contributor Author

oscscull commented Jul 3, 2025

Thanks to all for the extensive reviews. Apologies, I've got limited time to work on this so I expect I will proceed in bursts when I get a chance. I'll address all of these and add unit tests this week if possible.

@oscscull
Copy link
Contributor Author

oscscull commented Jul 3, 2025

Also check other room cards — some of it can contain unique logic and can require additional changes to support it.

this is a good point, I'll probably pull in several more to this PR.

@github-actions github-actions bot added the tests label Jul 6, 2025
@oscscull
Copy link
Contributor Author

@xenohedron thanks for the comprehensive review. I (hopefully) addressed every comment in some form. Thanks for your patience!

Copy link
Contributor

@xenohedron xenohedron left a comment

Choose a reason for hiding this comment

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

A couple remaining nits but overall I am happy with this. Thanks for your efforts!

public class RoomNameEffect extends ContinuousEffectImpl {

public RoomNameEffect() {
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a,
Copy link
Contributor

Choose a reason for hiding this comment

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

I had a look but sadly, it doesn't seem that clones work properly if I set the layer down. I suppose this is why I originally did this layer, as I did start with it in the lowest layer (also, I guess a characteristic defining ability is somewhat similar to name, in that it works everywhere).

I did add a test for a name altering clone, however, and it works fine. So probably it's alright?

Well if this is the way to get the results we need, then that's what it shall be for now

public class RoomNameEffect extends ContinuousEffectImpl {

public RoomNameEffect() {
super(Duration.WhileOnBattlefield, Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a,
Copy link
Contributor

Choose a reason for hiding this comment

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

Re: single effect - I did this mostly for readability as both are a bit wordy. If that's not a problem - I'll put them together - what do you think? I could do a couple sub methods perhaps. Neither of them really belong in the effects system but as discussed above I think this is a functional approach.

I think it should be a single RoomCharacteristicsEffect.
(It's never going to be correct to have one effect without the other, and some of the code is common.)

@JayDi85
Copy link
Member

JayDi85 commented Oct 15, 2025

@oscscull need starting topic update with actual status:

1 - detail changes from that PR (implemented rooms, added supported multiple names, improved zone changes, etc).

2 - add x2 TODO lists: one for your current implementation (if you plan to add more changes) and one for next PRs or changes (what’s miss and must be added/improved after that PR by you or another devs).

3 - add info about fully or partly supported rules (if you added all rooms related rules or there are something miss).

4 - add info about tests (is it cover all new rules and rooms logic/combos or need some improves later).

@oscscull
Copy link
Contributor Author

@xenohedron addressed these!

@oscscull
Copy link
Contributor Author

oscscull commented Oct 15, 2025

Adding some screenshots for context
Screenshot 2025-10-15 at 23 51 21
Screenshot 2025-10-15 at 23 51 39
Screenshot 2025-10-15 at 23 52 00
<img width="966" height="589" alt="Screenshot 2025-10-15 at 23 52 43" src="https://github.com/user-attachments/assets/6d2512b3-939a-4c8d-9a66-88608348362 />
Screenshot 2025-10-15 at 23 53 15

Copy link
Contributor

@xenohedron xenohedron left a comment

Choose a reason for hiding this comment

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

Thanks for all your work implementing rooms!

@xenohedron xenohedron merged commit f7be842 into magefree:master Oct 16, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants