Jump to content


Photo

Trying To Make A Card Game...


  • Please log in to reply
9 replies to this topic

#1 Jon Echidna

Jon Echidna

    GMC Member

  • New Member
  • 2 posts

Posted 26 January 2008 - 10:52 PM

Hello to everyone here. I'm a newly registered user with GameMaker 7Pro. I've had some previous experience with BlitzBASIC, so I'm hoping that will be useful here.

I've had this idea for a card game for a while now and I'd like to turn it into a reality. I did some research and I'm using elements from both Yu-gi-oh! and Magic the Gathering.

Heres the basic rundown:

Players summon entities and use scrolls to defeat their opponent by either making them run out of cards or reducing thier Hit Points (HP) from 6000 to 0.

You have a Encounter Field where there are 2 rows for six zones. The first zone in the first row is your Cemetery. The zone below it is your Deck. The top row is where you summon your entities and the bottom is where you play your scrolls.

Monsters can be played in Atk mode (Vertical) or Def mode (Horizontal). There are no face-down position. All cards are played face-up.

There are two card types:

Entities (Equivalent to Monsters/Creatures)

There are several entity types, such as Mages, Reptilian, and Undead.

Scrolls (Equivalent to Magics/Spells)

There are three Scroll types: Basic, Permanent, and Swift (Equivalent to Quick-play/Instant)

__________________________________________________
______________

Unfortunately as much searching as I do I can't seem to find a decent tutorial that relates to creating card games. Everything seems to deal with RPGs/Shooters/Action games.

Heres what I've got so far:

Card Sprite (Front/Back/Sideways) (GIF)
Title Screen (GIF) (800x600)
Duel Field (GIF) (800x600)
Deck Sprite (GIF)
Small understanding of arrays (this was the only thing I found that even related to my game)

I want to know how to make my game similar to the YGO games for the DS or the PSP. The ones where you can see the cards you draw as well as placing them on the field/switching their battle positions. So heres my 'To do" list:

How to shuffle the deck
How to draw cards
How to assign effects to cards (Can I use the same generic sprite for different effects or do I have to make several sprites with their own coding?)
How to show your hand without revealing it to your opponent
How to place cards from my hand to the field
How to switch a cards position (from ATK to DEF)
How to search for cards in the deck and add them to the hand
How to send cards to the cemetery
How to program an AI so I can duel against it

I hope someone can help me with my little project. If anyone knows a tutorial that relates to what I'm looking for, please post a link. Any help I can get is really appreciated!

Thank you.

Edited by Jon Echidna, 26 January 2008 - 10:54 PM.

  • 0

#2 GameGeisha

GameGeisha

    GameGeisha

  • GMC Member
  • 6565 posts
  • Version:GM:Studio

Posted 27 January 2008 - 02:13 AM

I have experience with the TCG (or CCG) genre before, so I think I could explain a few things:
WARNING: Huge post ahead!

Hello to everyone here. I'm a newly registered user with GameMaker 7Pro. I've had some previous experience with BlitzBASIC, so I'm hoping that will be useful here.

Welcome to Game Maker. Your experience with BlitzBASIC will prove itself useful, as basic knowledge of programming language structure and semantics is a prerequisite for understanding GML, the internal scripting language of GM. Although the structure will not be exactly the same, I'm sure that you can adapt well as GML is quite easy to learn.

...
- Small understanding of arrays (this was the only thing I found that even related to my game)

When I created my engine, arrays proved to be not so useful. I recommend using the list data structure (ds_list_x functions).


As for you to-do list, I'll focus on major areas:

- Creating the deck
Go to Global Game Settings -> Constants, then create a constant named "deck" with a value of "ds_list_create()" (both without quotes). This is a subtle hack I discovered that creates a list-based deck the instant the game starts. You can also do the same for your hand and the cemetery (also known as "graveyard" or "discard pile"). Now that the deck is created you can easily do the following:

- Shuffle the deck:
//shuffledeck(): Shuffles the deck.
ds_list_shuffle(deck);
- Draw a card:
//drawcard(): Draws a card from the top of the deck and return its name.
var card;
card = ds_list_find_value(deck,0);
ds_list_delete(deck,0);
return card;
- Search for a card:
//search(cardname): Searches for a card from the deck and puts it in your hand. Returns whether the card exists in the deck.
var pos;
pos = ds_list_find_index(deck,argument0);
if (pos != -1) {
  ds_list_delete(deck,pos);
  ds_list_add(hand,cardname);
  return true;
}
else return false;


- The "entity" (also known as "creature" or "monster")
My game also had "entities" in them (known as "units"), and there were about 200 of them before a hard drive crash forced the project to end. Despite the numbers, all these "units" were based on one parent object: unit. For your case, I'll use the term entity.

Your basic entity object will be a bare shell from which all entities are derived. This entity object contain variables that allow you to directly control and modify their stats. From the information you provided, I can propose a basic set of variables which should be established in the object and their "default" values:
name=]"]]
This is not a conclusive list. As your game progresses, it may be necessary to add more control variables. My game made use of at least 30 local ones and over 20 global ones managed by a central controller. However, I'm sure that you can see how battle positions can be switched (set pos to true or false as needed).


- Assigning statistics
My game made use of a dictionary function, which holds the statistics for all cards. It is in the form of a huge switch block, looking somewhat like this:
//atklookup(card): Returns the ATK value of card.
switch(argument0) {
  case "Entity A": return 1000; break;
  case "Hammer entity": return 2600; break;
  case "Sitting duck": return 0; break;
  //...
}
When you summon an entity, you can refer back to these values while setting up an entity object. These values will establish an entity tailored to your specs.


- Graveyard and hand
As mentioned before, you can use lists for these. The graveyard is pretty straight forward, as adding new cards to the graveyard can be done like this with a list-based one:
//add_graveyard(card): Adds a card to the graveyard.
//WARNING: This doesn't check where it came from!
ds_list_add(graveyard,argument0);
As seen in the draw() and search() functions in the session discussing the deck, similar actions can be taken to modify the hand's contents.
If you don't want to see your opponent's hand, you can create an object which draws only the images pertaining to the cards in YOUR hand. Since lists are invisible (they're just variables), you won't know what's in your opponent's hand.


- AI
This is the toughest one! However, there are a few tips to creating a good TCG AI:
- Know the combos. You may want to play around with the cards a little to see the interactions between effects, and then you'll need to teach the AI what combos to make and which ones to avoid. This mechanism will be extremely complex, and I have yet to accomplish a fully functional system in my game.
- It shouldn't break rules. This is a basic one, yet this issue bugged me for a large part of the initial development process.
- It should know when to attack and what to attack with. The AI should also make informed decisions of putting entities in ATK or DEF position.


- Assigning effects
Another hard one! My method of assigning effects is to use variables consisting of code in string form, then fed through the execute_string() function when needed. In my game, I had a series of event triggered ones, looking somewhat like this:
//event variables
ev_drawcard = "";
ev_onsummon = "";
ev_killed = "";
//...
For static ones (e.g. can't attack), you may want to consider using individual variables that are set to true when active. Activated ones (the effects with ":" from Magic) can have separate variables reserved for them (e.g. ev_fx1).


My game (called Dexterity TCG) is unfortunately discontinued due to a hard drive crash, but a usable source remains available here. Feel free to PM me if you have trouble interpreting the source or have any questions to ask.

Xekko
  • 0
Latest Releases:
  • GMLinear --- Matrix and vector math in one line!
  • GMAssert --- Debug invalid values and write quick unit tests with ease!
  • KameGMS --- Bring up TortoiseSVN and TortoiseGit dialogs from within the GMS IDE!
  • JSOnion v1.1 --- The stink-free way to handle JSON! (even deeply nested ones)

#3 smaza

smaza

    GMC Member

  • GMC Member
  • 78 posts
  • Version:GM8

Posted 27 January 2008 - 02:31 AM

I hope I can help with some of the things...

How to draw cards
Well, first off, it would be easiest to use data structures to do the deck, I suggest a stack.

Every card would have an ID, like a monster could be card 27, and another monster card 13, and a spell is card 62 etc.
Every individual card would have an ID.

These would, of course, use arrays, i.e. card[62,1] could be the name of card 62, ie "Hairy Armpit of Doom".

A stack is like a pile, i.e. the last card put on the top is the first card to be taken off.

Not sure about shuffle, but to draw a card, you have arrays for hand and a ds_stack for the deck.

To draw a card...
in the create event
//creates the stack for the deck
deck=ds_stack_create()
//initialises the hand
//change 7 to the no. cards possible in a hand
hand[7]=0


in the event where it draws, maybe an alarm or the step
var draw;
draw=-1
//returns the first empty slot in your hand
do
{
draw+=1
}
until (hand[draw]=0)
//wait a minute...

Wait a minute... never mind, while writing this, someone else ended up writing a much easier way of doing this.
so ignore this.
  • 0
yo

#4 Jon Echidna

Jon Echidna

    GMC Member

  • New Member
  • 2 posts

Posted 30 January 2008 - 02:54 AM

Thank you and I appreciate both of your replies.

Xekko, I've pm you since you seem to know exactly what I wish to know. Thanks for your time!
  • 0

#5 _204262

_204262

    GMC Member

  • New Member
  • 3 posts

Posted 09 May 2011 - 06:51 PM

hai.. all,
im a newbee here, im looking n try to creating card game like poker, solitaire, trump or Bridge. anyone wanna help me about that.
thank's before.
  • 0

#6 RobbieGoD316

RobbieGoD316

    GMC Member

  • New Member
  • 19 posts
  • Version:GM:Studio

Posted 04 June 2015 - 03:44 PM

Newbie question here, in the search example you provided where does the argument0 come from?

//search(cardname): Searches for a card from the deck and puts it in your hand. Returns whether the card exists in the deck.
var pos;
pos = ds_list_find_index(deck,argument0);
if (pos != -1) {
  ds_list_delete(deck,pos);
  ds_list_add(hand,cardname);
  return true;
}
else return false;
}

  • 0

#7 GameGeisha

GameGeisha

    GameGeisha

  • GMC Member
  • 6565 posts
  • Version:GM:Studio

Posted 04 June 2015 - 04:44 PM

The value for argument0 comes from the argument passed into the script.

 

In this example, "Flamespinner" is the argument to the script, and this value would appear in argument0.

search("Flamespinner");

See this Manual entry for details.

 

GameGeisha

 

PS: Don't necro-post, this topic dates back 7 years.


  • 0
Latest Releases:
  • GMLinear --- Matrix and vector math in one line!
  • GMAssert --- Debug invalid values and write quick unit tests with ease!
  • KameGMS --- Bring up TortoiseSVN and TortoiseGit dialogs from within the GMS IDE!
  • JSOnion v1.1 --- The stink-free way to handle JSON! (even deeply nested ones)

#8 RobbieGoD316

RobbieGoD316

    GMC Member

  • New Member
  • 19 posts
  • Version:GM:Studio

Posted 04 June 2015 - 07:37 PM

Sorry for necro-posting  :skull:

 

Thanks for the answer regardless.  


  • 0

#9 naidim

naidim

    GMC Member

  • New Member
  • 1 posts
  • Version:GM:Studio

Posted 02 October 2015 - 10:09 PM

Sorry in advance for the necro-post, but when it comes to coding old answers can still be good answers.

 

When trying the above example to create a ds_list in GM:S it appears to create the list "deck" without error but won't add anything to it. From memory this is what I tried:

 

In Macros: deck:ds_list_create()

if (ds_exists(deck, ds_type_list)) {
  ds_list_add(deck, 10);
  show_message(string(ds_list_size(deck))); // displays 0
}

However if I don't use the Macros and instead add globalvar deck; before my code it works just fine (without the color-coding of "deck" :( ). Is this a purposeful change in Studio, or a bug?


  • 0

#10 GameGeisha

GameGeisha

    GameGeisha

  • GMC Member
  • 6565 posts
  • Version:GM:Studio

Posted 02 October 2015 - 10:29 PM

When trying the above example to create a ds_list in GM:S it appears to create the list "deck" without error but won't add anything to it. From memory this is what I tried:

 

In Macros: deck:ds_list_create()

if (ds_exists(deck, ds_type_list)) {
  ds_list_add(deck, 10);
  show_message(string(ds_list_size(deck))); // displays 0
}

However if I don't use the Macros and instead add globalvar deck; before my code it works just fine (without the color-coding of "deck" :( ). Is this a purposeful change in Studio, or a bug?

 

This is a change in GMS dating from the 1.3.x period, when Macros replaced Constants. Constants evaluate their values once upon startup, while Macros evaluate their values upon every reference. In this case, every reference to deck in GMS created a new list.

 

You could use globalvar deck; at the beginning of the game to get the same behaviour as in GM8, but for cross-platform safety I recommend using global.deck instead.

 

GameGeisha


  • 0
Latest Releases:
  • GMLinear --- Matrix and vector math in one line!
  • GMAssert --- Debug invalid values and write quick unit tests with ease!
  • KameGMS --- Bring up TortoiseSVN and TortoiseGit dialogs from within the GMS IDE!
  • JSOnion v1.1 --- The stink-free way to handle JSON! (even deeply nested ones)