Magic the Gathering Client

I’ve been working some on a Magic the Gathering client for Roblox. It’s at a point where you can actually play a game on it now. Place is Uncopylocked, feel free to take a look at the code.

Some Usage notes:

  • You can undo mana ability activations by pressing “Z”
  • You can pass until the next turn by pressing “A”

General Project Structure:

  • MagicGameState in ReplicatedStorage is the central model class that runs everything
  • MagicClientView → MagicGameView in ReplicatedStorage.View are the root view/controllerss that display the current state
  • The network communication is all done through one RemoteEvent in ReplicatedStorage.MagicInterface
  • The idea is that the client sends an “I’m ready” event to the server, when it’s done local loading, and then the server sends it all of the data it needs and starts sending it relevant game events once it has gotten that ready event
  • The entry points are ServerScriptService.MagicServer for the server and MagicClient_ConnectionSetup and MagicClient_ViewSetup for the model and views respectively. MagicClientGameList ties the views and models together

Magic Related Stuff:

  • ReplicatedStorage.CardDef is where the cards are defined
  • “Information Privacy” is preserved, the clients don’t know any information that they shouldn’t be able to (even if you were to hack the client you couldn’t find out what’s in your opponents hand / deck)
  • All of the spell casting / ability activation is done locally first before being replicated to the server for it to repeat, so that the interface feels perfectly responsive. The approach used is to perform all of the actions on the game state during casting / ability activation, whether on the client or server, through an “executeAction” method on the game state. When actions are executed on a client, they are just executed there. When actions are executed on the server, replicate the changes they make to each client. However, we don’t want the client who did some local actions in casting a spell or activating an ability to do those actions twice (once itself, once when the replication comes in), So, when the server is performing the actions it has an “current player to ignore”, which it doesn’t replicate actions to.
  • The real meat of the MagicGameState is in “updateObjectsAndPlayers”, which takes and applies all static abilities and effects to all of the objects currently on the battlefield, in players hands, etc.
  • Stuff that works right now: Static Abilities/Effects, Triggered Abilities/Effects, Activated Abilities and Casting Spells as long as the only require mana as a cost (they don’t have additional costs like sacrificing things) and have no targets.
  • Stuff to still do: Spells / the targeting system. Replacement effects (the framework is there). Allowing card effects to make requests like searching your library or choosing things to sacrifice / discard. “Revealing” cards from opponents hands / libraries.
7 Likes

I was just experimenting with xmage and also forge, two free magic clients. Getting the guis and user experience right is super hard. They both have pros and cons. Yours looks very nice.

Would you consider a multi step undo button? Or just the mana ability activations?

Lol.

Can’t wait to try on PCS, though. Looks neat so far from what I can see.

1 Like

Turn 1, played two lands.

Btw @stravant thanks for all the cards you gave me when you interned here. I am an addicted magic player now.

And then you got others addicted to it, didn’t you

it never ends

magic, not even once

(Yeah I noticed it gives three land drops per turn like an effect was in play, weird)

He did :sweat:

Good to know my proselytizing was successful. Are you at the point where you go down to the Channel Fireball game center or similar for big events yet? Or have you just gone to local stuff like Gator Games for a prerelease?

I have it set to 3 land drops / turn right now for debugging purposes. Can be changed in MagicGameState::initialize where it sets MaxLandPlays for each player.

  • Added graveyards.
  • Made cards look like actual Magic cards.
  • Made floating boxes like the stack resizable / draggable.

I get just a blue skybox :-/

Not sure what was wrong when you tried it, I must have uploaded a non-working intermediate. It should work now.

I added a lobby and implemented a bunch more features (additional costs, replacement effects, targeting, end-of-game handling, modal spells, etc). You can actually play a game against someone now (no matches / sideboarding yet).

I have all of the modern burn maindeck implemented minus Rift Bolt (it will take a couple more features to make Suspend work).