Skip to content

Commit a228a6c

Browse files
authored
Wiki update (Card-Forge#9313)
1 parent 08c2c64 commit a228a6c

File tree

170 files changed

+203
-221
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+203
-221
lines changed

docs/AI.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@ Please understand, the AI is still the AI, and it's limitations exist even again
1919
## Syntax
2020
`sim -d <deck1[.dck]> ... <deckX[.dck]> -D [path] -n [N] -f [F] -t [T] -p [P] -q`
2121

22-
In linux and mac, command line arguments are not currently passed through the sh script, please call `java -jar` manually, instead of the exe.
2322
- `sim` - "Simulation Mode" forces Forge to not start the GUI and automatically runs the AI matches in command line. Enables all other switches for simulation mode.
2423
- `-d <deck1[.dck]> ... <deckX[.dck]>` - Space separated list of deck files, in `-f` game type path. (For example; If `-f` is set to Commander, decks from `<userdata>/decks/commander/` will be searched. If `-f` is not set then default is `<userdata>/decks/constructed/`.) Names must use quote marks when they contain spaces.
2524
- `deck1.dck` - Literal deck file name, when the value has ".dck" extension.
2625
- `deck` - A meta deck name of a deck file.
2726
- `-D [path]` - [path] is absolute directory path to load decks from. (Overrides path for `-d`.)
2827
- `-n [N]` - [N] number of games, just flat test the AI multiple times. Default is 1.
2928
- `-m [M]` - [M] number of matches, best of [M] matches. (Overrides -n) Recommended 1, 3, or 5. Default is 1.
30-
- `-f [F]` - Runs [F] format of game. Default is "constructed" (other options may not work, list extracted from code)
29+
- `-f [F]` - Runs [F] format of game. Default is "constructed"
3130
- `Commander`
3231
- `Oathbreaker`
3332
- `TinyLeaders`
@@ -41,10 +40,9 @@ In linux and mac, command line arguments are not currently passed through the sh
4140
- `Swiss` - See wikipedia for [Swiss Pairing Tournaments](https://en.wikipedia.org/wiki/Swiss-system_tournament)
4241
- `-p [P]` - [P] number of players paired, only used in tournament mode. Default is 2.
4342
- `-q` - Quiet Mode, only prints the result not the entire log.
43+
- `-c [S]` - Clock flag, maximum time of [S] seconds before calling the match a draw. Default is 120.
4444

4545
## Examples
46-
In linux and macos you must run forge by evoking java and calling the jar, currently command line parameters are not passed through the script. The forge jar filename is truncated in these examples from `forge-whatever-version-youre-on.jar` to `forge.jar`.
47-
4846
In Windows, if you use the EXE file as described below, the simulation runs in the background and output is sent to the forge log file only. If you want to have output to the console, please use the `java -jar` evocation of forge.
4947

5048
To simulate a basic three games of two decks (deck1 and deck2 must be meta deck names of decks in `<userdata>\decks\constructed\`):
@@ -55,10 +53,6 @@ To simulate a single 3-player Commander game (deck1, deck2, and deck3 must be me
5553
- Windows/Linux/MacOS: `java -jar forge.jar sim -d deck1 deck2 deck3 -f commander`
5654
- Windows: `.\forge.exe sim -d deck1 deck2 deck3 -f commander`
5755

58-
To simulate a round robin tournament; best of three, with all decks in a directory:
59-
- Windows/Linux/MacOS: `java -jar forge.jar sim -D /path/to/DecksFolder/ -m 3 -t RoundRobin`
60-
- Windows: `.\forge.exe sim -D C:\DecksFolder\ -m 3 -t RoundRobin`
61-
6256
To simulate a swiss tournament; best of three, all decks in a directory, 3 player pairings:
6357
- Windows/Linux/MacOS: `java -jar forge.jar sim -D /path/to/DecksFolder/ -m 3 -t Swiss -p 3`
6458
- Windows: `.\forge.exe sim -D C:\DecksFolder\ -m 3 -t Swiss -p 3`

docs/Card-scripting-API/AbilityFactory.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,12 @@ Parameters (all optional):
395395
- `NumDef$` - pumps Toughness
396396
- `KW$` - gives keywords
397397

398+
Due to its generic nature Pump is also the conventional "helper AF" when an effect requires more than one target with different restrictions, e.g. *Political Trickery*:
399+
```
400+
A:SP$ Pump | ValidTgts$ Land.YouCtrl | TgtPrompt$ Choose target land you control | SubAbility$ DBExchange | SpellDescription$ Exchange control of target land you control and target land an opponent controls. (This effect lasts indefinitely.)
401+
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Land.OppCtrl | TgtPrompt$ Choose target land an opponent controls
402+
```
403+
398404
## Regenerate
399405
Regenerate is for creating regeneration shields.
400406

docs/Card-scripting-API/Card-scripting-API.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Creatures with "Multiple" in this SVar will always be preferred when the AI ench
182182

183183
* `EquipMe:{Multiple/Once>}`
184184

185-
Creatures with "Multiple" in this SVar will always be prefered when the AI equips, creatures with "Once" only if they are not equipped already.
185+
Creatures with "Multiple" in this SVar will always be preferred when the AI equips, creatures with "Once" only if they are not equipped already.
186186

187187
* `EndOfTurnLeavePlay:True`
188188

@@ -210,7 +210,13 @@ Uses operand-operator syntax, where `{cmp}` is a comparator:
210210
**GE** *Greater than or Equal*
211211
**GT** *Greater Than*
212212

213-
*Tip:* the AI is smart enough to not play permanents if they have ineffective ETB triggers.
213+
*Tip:* the AI is (usually) smart enough to not play permanents if they have obviously ineffective ETB triggers.
214+
215+
Here's a good example from *Eldrazi Monument* where the extra heuristics try to avoid playing it without a good enough boardstate:
216+
```
217+
SVar:NeedsToPlayVar:Y GE3
218+
SVar:Y:Count$Valid Creature.YouCtrl
219+
```
214220

215221
* `NonStackingEffect:True`
216222

docs/Card-scripting-API/Statics.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ By default `Affected-/EffectZone` are both Battlefield.
1010
Here's an example for layer 7c:
1111
`Affected$ Creature.YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Creatures you control get +1/+1.`
1212

13+
`CharacteristicDefining$ True`
14+
1315
See [StaticAbility.generateLayer()](https://github.com/Card-Forge/forge/blob/master/forge-game/src/main/java/forge/game/staticability/StaticAbility.java) for the full list of params on each Layer.
1416

1517
*Note:* Layer 1 is currently only implemented as a resolving effect instead.

forge-ai/src/main/java/forge/ai/AiController.java

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -400,30 +400,13 @@ private boolean checkETBEffectsPreparedCard(final Card card, final SpellAbility
400400
return rightapi;
401401
}
402402

403-
private static List<SpellAbility> getPlayableCounters(final CardCollection l) {
403+
private static List<SpellAbility> getPlayableCounters(final CardCollection all) {
404404
final List<SpellAbility> spellAbility = Lists.newArrayList();
405-
for (final Card c : l) {
406-
if (c.isForetold() && c.getAlternateState() != null) {
407-
try {
408-
for (final SpellAbility sa : c.getAlternateState().getNonManaAbilities()) {
409-
// Check if this AF is a Counterspell
410-
if (sa.getApi() == ApiType.Counter) {
411-
spellAbility.add(sa);
412-
} else {
413-
if (sa.getApi() != null && sa.getApi().toString().contains("Foretell") && c.getAlternateState().getName().equalsIgnoreCase("Saw It Coming"))
414-
spellAbility.add(sa);
415-
}
416-
}
417-
} catch (Exception e) {
418-
// facedown and alternatestate counters should be accessible
419-
e.printStackTrace();
420-
}
421-
} else {
422-
for (final SpellAbility sa : c.getNonManaAbilities()) {
423-
// Check if this AF is a Counterspell
424-
if (sa.getApi() == ApiType.Counter) {
425-
spellAbility.add(sa);
426-
}
405+
for (final Card c : all) {
406+
CardState state = c.isForetold() && c.getAlternateState() != null ? c.getAlternateState() : c.getCurrentState();
407+
for (final SpellAbility sa : state.getNonManaAbilities()) {
408+
if (sa.getApi() == ApiType.Counter) {
409+
spellAbility.add(sa);
427410
}
428411
}
429412
}

forge-ai/src/main/java/forge/ai/AiDeckStatistics.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public AiDeckStatistics(float averageCMC, float stddevCMC, int maxCost, int maxC
3535
this.numLands = numLands;
3636
}
3737

38-
public static AiDeckStatistics fromCards(List<Card> cards) {
38+
public static AiDeckStatistics fromCards(Iterable<Card> cards) {
3939
int totalCMC = 0;
4040
int totalCount = 0;
4141
int numLands = 0;
@@ -72,7 +72,6 @@ public static AiDeckStatistics fromCards(List<Card> cards) {
7272
// find the sources
7373
// What about non-mana-ability mana sources?
7474
// fetchlands, ramp spells, etc
75-
7675
}
7776

7877
return new AiDeckStatistics(totalCount == 0 ? 0 : totalCMC / (float)totalCount,
@@ -84,7 +83,6 @@ public static AiDeckStatistics fromCards(List<Card> cards) {
8483
);
8584
}
8685

87-
8886
public static AiDeckStatistics fromDeck(Deck deck, Player player) {
8987
List<Card> cardlist = new ArrayList<>();
9088
for (final Map.Entry<DeckSection, CardPool> deckEntry : deck) {

forge-ai/src/main/java/forge/ai/ComputerUtilAbility.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,14 @@ public static List<SpellAbility> getSpellAbilities(final CardCollectionView l, f
9090
}
9191

9292
public static List<SpellAbility> getOriginalAndAltCostAbilities(final List<SpellAbility> originList, final Player player) {
93-
final List<SpellAbility> newAbilities = Lists.newArrayList();
94-
9593
List<SpellAbility> originListWithAddCosts = Lists.newArrayList();
9694
for (SpellAbility sa : originList) {
9795
// If this spell has alternative additional costs, add them instead of the unmodified SA itself
9896
sa.setActivatingPlayer(player);
9997
originListWithAddCosts.addAll(GameActionUtil.getAdditionalCostSpell(sa));
10098
}
10199

100+
final List<SpellAbility> newAbilities = Lists.newArrayList();
102101
for (SpellAbility sa : originListWithAddCosts) {
103102
// determine which alternative costs are cheaper than the original and prioritize them
104103
List<SpellAbility> saAltCosts = GameActionUtil.getAlternativeCosts(sa, player, false);
@@ -323,10 +322,11 @@ public int compareEvaluator(final SpellAbility a, final SpellAbility b, boolean
323322
a1 += getSpellAbilityPriority(a);
324323
b1 += getSpellAbilityPriority(b);
325324

326-
// If both are creature spells sort them after
325+
// if both are creature spells sort them after
327326
if (safeToEvaluateCreatures) {
328-
a1 += Math.round(ComputerUtilCard.evaluateCreature(a) / 100f);
329-
b1 += Math.round(ComputerUtilCard.evaluateCreature(b) / 100f);
327+
// try to align the scales: if priority swings in either direction extra evaluation matters less
328+
a1 += Math.round(ComputerUtilCard.evaluateCreature(a) / (10.5f + Math.abs(a1)));
329+
b1 += Math.round(ComputerUtilCard.evaluateCreature(b) / (10.5f + Math.abs(b1)));
330330
}
331331

332332
return b1 - a1;

forge-game/src/main/java/forge/game/ability/effects/DigEffect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ protected String getStackDescription(SpellAbility sa) {
3535
} else {
3636
final int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa);
3737
final String toChange = sa.getParamOrDefault("ChangeNum", "1");
38-
final int numToChange = toChange.startsWith("All") ? numToDig : AbilityUtils.calculateAmount(host, sa.getParam("ChangeNum"), sa);
38+
final int numToChange = toChange.equals("All") || toChange.equals("Any") ? numToDig : AbilityUtils.calculateAmount(host, sa.getParam("ChangeNum"), sa);
3939

4040
String verb = " looks at ";
4141
if (sa.hasParam("DestinationZone") && sa.getParam("DestinationZone").equals("Exile") &&

forge-game/src/main/java/forge/game/card/Card.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,10 +3446,8 @@ public final boolean canProduceColorMana(final Set<String> colors) {
34463446
if (CardUtil.getReflectableManaColors(mana).contains(s)) {
34473447
return true;
34483448
}
3449-
} else {
3450-
if (mana.canProduce(MagicColor.toShortString(s))) {
3451-
return true;
3452-
}
3449+
} else if (mana.canProduce(MagicColor.toShortString(s))) {
3450+
return true;
34533451
}
34543452
}
34553453
}
@@ -7662,8 +7660,8 @@ public List<SpellAbility> getAllPossibleAbilities(final Player player, final boo
76627660
if (sa.isAdventure() && isOnAdventure()) {
76637661
continue; // skip since it's already on adventure
76647662
}
7665-
//add alternative costs as additional spell abilities
76667663
abilities.add(sa);
7664+
//add alternative costs as additional spell abilities
76677665
abilities.addAll(GameActionUtil.getAlternativeCosts(sa, player, false));
76687666
}
76697667

@@ -7683,7 +7681,6 @@ public List<SpellAbility> getAllPossibleAbilities(final Player player, final boo
76837681
// Add Modal Spells
76847682
if (isModal() && hasState(CardStateName.Backside)) {
76857683
for (SpellAbility sa : getState(CardStateName.Backside).getSpellAbilities()) {
7686-
//add alternative costs as additional spell abilities
76877684
// only add Spells there
76887685
if (sa.isSpell() || sa.isLandAbility()) {
76897686
abilities.add(sa);

forge-gui/res/cardsfolder/a/abomination_of_llanowar.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ K:Menace
77
S:Mode$ Continuous | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of Elves you control plus the number of Elf cards in your graveyard.
88
SVar:X:Count$Valid Elf.YouCtrl/Plus.Y
99
SVar:Y:Count$ValidGraveyard Elf.YouOwn
10-
SVar:NeedsToPlayVar:X GE1
1110
SVar:BuffedBy:Elf
1211
DeckNeeds:Type$Elf
1312
Oracle:Vigilance; menace (This creature can't be blocked except by two or more creatures.)\nAbomination of Llanowar's power and toughness are each equal to the number of Elves you control plus the number of Elf cards in your graveyard.

0 commit comments

Comments
 (0)