• 2D
  • Mock-up for a non-interactive combat system for FreeOrion

Thanks to the kind person who's helping me, I'm trying chunuiyu's Card Framework, which is simpler than the other two and quite well documented.

And it made me think of something else : since I'll be using cards for the orders given, it could be interesting to have those have card values.

Not sure yet how to decide the value of each card in the final game; I guess that for the mock-up just drawing them at random (it's very unlikely that a battle will use more than 52 cards) should work fine.

Then we make those cards follow the rules of Poker, the cards representing tactical brilliance : for each square, big square, row, column (and for the checkerboard in general), at combat resolution phase, we compare "hands" and the winner gets an advantage for what happens there.

Cards add for each level : that is, the hand for square C1R1 is composed of the card (if any) played at square C1R1, the card (if any) played at Column1, the card (if any) played at Row1, the card (if any) played for the "big square" going from C1R1 to C3R3, the card (if any) played at Big Column1-3, the card (if any) played at Big Row1-3, and the card (if any) for the whole checkerboard.
These hands are known after each round, so if there are more than 5 cards in these hands, the player chooses which ones to "discard" (that is, the order will still be executed, but the card won't be used for comparing the hand to the enemy's).

Actually, what would be even more interesting would be to have each player decide which game he'll be playing with his cards, but I haven't found a way yet to make that work so I'll drop it for this mock-up.
And to avoid complexifying the mock-up too much, it may be better to have the option to use these card values/poker comparisons or not, so it's possible to learn how it works first without the poker part.

Anyway, Poker is interesting because of bets, and I'm specifically designing a non-interactive combat system, so alas I can't have interactive bets in it (or maybe at a meta level ? but I can't think of something interesting right now).

So what I'd have is a sum of "audacity points" for each player, and in the design phase the player bets these audacity points on each location (for each round, while the sum is for the entire 4-rounds battle; so a player can't bet on each location unless they have a huge amount of Audacity Points, which they won't).

Bets, contrary to cards, do not add for different levels of each location : you bet either on the column or the square (or the row, or whatever, I mean). You can bet on both if you spend audacity on both, but if you bet let's say 2 Audacity on square C1R1 and 1 on row 1, you have 2 A on square C1R1, not 3.

To win the upper hand in any location, the player must have both bet more or equal than the opponent, and have a better hand of cards (tactical brilliance doesn't work without audacity).
If the player who win the bets has a lower hand, nothing happens (audacity doesn't work without tactical brilliance).

Obviously this should incite players to bet on the locations where their hand is the best, which doesn't make for a very interesting game.
I mean, the game works if they try to bet on where their hand will best their enemy's (since they can't know it for sure, which makes the betting interesting), but if they just bet there they have their strongest hand (comparatively to their other hands, which they entirely know), it's not very challenging.

So I guess that each time the player plays a card, as long as he still has Audacity Points available, he has to make a bet on a specific location where he hasn't put a bet yet (and that bet can't be changed after that).

That means I guess that a player chooses one order, gets the card value assigned to that order ("ace of spade" for example) and has to play this order now - no backsies¹.

Also, if a player wins the bet and the hand, it means that their audacity and tactical brilliance pays off, and s/he gets an advantage on that location that is multiplied by the total of the bets put there (audacity backfires on the loser).
(I'm not entirely sure of the effect of that last rule on the balance of the game, so if someone has a better understanding of it/more ideas to help this balance, I'd be glad to hear them)

Which advantage is chosen by the player (on a per-turn basis rather than per-location I guess, so as to avoid clogging the UI) : more damage dealt, less damage received, more speed for their ships, less speed for enemy ships, better stealth, easier achievements, ...


So what that means for the Godot scene :

  • A counter for the Audacity points

  • A label area (with a drop-down menu ?) to choose the advantage provided by having the upper hand during the current round

  • Near each card slot a way to place a bet (another counter I guess ?). One too on each square (since square won't have dedicated card slots)

  • At the end of each round in the design phase, an animation showing each location with more than 5 cards, and a way to signal which excess cards will not count for the hand

  • A way to check the hand for each location for the current round, at every step of the game

  • In the combat resolution phase, an animation showing the bets and hands for each location, and another one showing the locations where each player won

  • Probably an animation on each location where one player won, to show what advantage applies

I think that's it ?



Once it's integrated in the full FreeOrion game, one problem is that once a player has met the enemy combat doctrine, its bets are well known and it's easy to tailor counter-bets against them.
Note though that tailoring combat doctrines to counter enemy combat doctrines is the core principle of this non-interactive combat system (as you never know which combat doctrine the enemy will choose among the many they have).

Still, it's probably useful to avoid tying completely the bets to the combat doctrine.
Probably, allowing to change one's bets a little (maybe one Audacity Points each turn ? or a small number tied to the Empire's characteristics ?) would make the game more interesting.



¹ Another option would have the player see the card values for each possible order, and each type s/he picks a card s/he has to play this card, and another card for the same order - but with a different card value - is drawn and added to the possible order cards. The value for the new card would be known after the player has picked their card, but before they play it.
So if s/he picked a "move&shoot" order bearing a five of hearts, and the new "move&shoot" card is a king of diamonds, the player may choose to put the five of hearts in a different location than they previously intended, in order to put the king of diamonds where it brings the most benefits.

Actually making the "tactical brilliance" be the value of the card, and have the hands represent command&control seems more fitting, and allows the drawing of cards to be less random (though I'm not sure about how : maybe by removing some lower-value cards from the deck ?).

Also (still thinking out loud) if FreeOrion finally gets its "themes" (Organic, Energy, Robotic, Crystalline, Flux...) it would be possible to use these for the cards (instead of space, hearts, diamonds,...).
Not sure how though.

Still thinking out loud :
With the betting system I described, it's obvious that if the player has a good card that works for the whole armada, it's better to use it for the whole checkerboard and bet all their audacity on it.
So I guess that I should make bets cost 1 audacity on a square, 2 on a row, column and big square, 4 on big rows and big columns, and 9 on the whole board.
So getting +10% on the whole board is probably less efficient than getting +90% on a specific square, if you know what you're doing...

Also, a betting game that isn't interactive is a bit of a paradox, so I guess that I should try to make the bets visible, but I'm not sure how to do that (due to the non-interactive part, and the fact that a player should have many combat doctrines, especially at the end).

Maybe make bets on the whole board visible, and depending on certain game factors make also some other bets visible ?
That is, having a panel that shows for each enemy the number of bets on each square/column/whatever, either summing all the combat doctrines or specifying the number of combat doctrines that have a bet there ?

Another option would have generic bets (not specific to a combat doctrine) that could be put on a generic board, and be added to the bets of each combat doctrine.
That would represent "advanced training" or something similar.
Maybe even betting not Audacity at this level, but "Proficiency", and winning the hands where these bets are placed would provide better "tactical brilliance" ? That is, affecting the drawing of cards to produce better hands...



Also, if I go with the idea that cards values are decided when the player opens the orders pile : since the idea for this combat system is to bring tactical finesse, there will be a large number of orders.
Which would mean have the player get a large number of cards to choose from - not the principle of poker.
So I guess that I need not one but a few piles for the orders : like "combat orders", "movement orders", and the like.

That way each pile would have around 5 orders.

Not sure if the cards values should stick for the round, or be redefined each time the player takes a new card.
The second option adds the randomness that is inherent to the idea of card games, though.

18 days later

I want to have the cards taken from the pile change their size when they enter the checkerboard (so that they can fit into the card slots), so I designed an Area2D (with a CollisionShape2D as its child) and tried to connect the "area entered" signal.
But I can't find a way to connect it to the card.tscn scene ?
What am I supposed to do ?

Cards are not objects handled in the main.tscn, they are used by the Card Framework, so I'm not sure that I can even call them directly from the main.tscn scene...

15 days later

I did a quite horrible hack and added an Area2D and CollisionShape to the Card scene (as a child of their TextureRect) so I was able to use the AreaEntered signal, by checking if the area is in the right group.
Actually I tried two methods :

  • Using the AreaEntered signal on the Area2D for the checherboard, and checking if the area that has entered is in the group "Cards", then setting the area.get_parent().get_parent().get_parent() scale to half what it was (with =Vector2(0.5,0.5))
  • Using the AreaEnterd signal on the Card Area2D and checking if the area that has entered is the CheckerboardDroppableZone then setting self.scale to half what it was.

Both work, but both bring two problems :

  • One I sort of understand, I can't find a way to scale them back to normal size when they exit the area.
    I guess that I could instead of scaling the card, just assign them a variable (like "is _in_which_area") and then use match on the process() function to set their scale according to where they are at the current moment ?
  • One I don't understand at all : when reduced, the cards are shimmering.
    My code is there if someone wants to try (launch the main_alt.tscn scene).
4 days later

When I remove the horrible hack, both problems disappear...

6 days later

The Card Framework is quite well documented, but not entirely.
They use a "drop_zone" scene (instantiated in the code of the CardContainer) without the documentation mentioning it at all...
I suppose that it's for piles that are able to receive cards but it would be nice to have clear explanations.
Especially, these dropzones have "sensors" in their code, also without any documentation of the feature.
I suppose that the sensors are there to detect whether there are cards in the area that they cover, but I'm not 100% sure and I don't fully understand the code.

I tried to look at the code again to identify how the dropzone works but I keep getting lost in the abundancy of scenes and functions.
Is there a good tool to help visualize the interactions between those ?

Not necessarily automatic (I don't think that exist), but something that I could fill along the way while I analyze the code, so that I don't forget what I understood (which is what happens now : I understand a thing and the next day if I look again at this part of the code I don't understand it anymore).

From what I understand the dropzone seem to only check if the drop is enabled (from an exported variable and, in some scenes, according to game rules).
So I tried to remove the code in tableau.tscn that conditions droppability but the cards still aren't dropped in the dropzone... I don't understand why, especially since the variable is set by default in the inspector as "drop enabled".

Also that made me think : the Design phase (the part I'm currently working on; I'm less and less convinced that I'll do the Resolution phase in Godot, as this Resolution will later be done server-side in C++ so all my code would be wasted; maybe I'll do a very minimal one so as to be able to show the mock-up, though) is made of many rounds (four, by default).
On each round the Dropzones ("tableau" as of now) can receive cards.
So, should I make a new tableau/dropzone for each round ?
What I planned until now is to have the same tableau/dropzone get the cards for the four rounds, but now I wonder if it's a good design.
Of course the player will need to be able to access previous round's cards (to check what they are, not to modify them).
lienrag