Skip to content

Commit dd35f97

Browse files
authored
Cleanup scripting API first pass (Card-Forge#9070)
1 parent ee045d8 commit dd35f97

File tree

8 files changed

+490
-416
lines changed

8 files changed

+490
-416
lines changed

docs/Card-scripting-API/AbilityFactory.md

Lines changed: 262 additions & 304 deletions
Large diffs are not rendered by default.

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

Lines changed: 104 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
A reference guide for Scripting Cards using the API parsed by the Forge
2-
Engine.
1+
A reference guide for scripting cards using the API parsed by the Forge engine.
32

4-
### Base Structure
3+
# Base Structure
54

6-
By opening any file in the /res/cardsfolder folder you can see the basic
7-
structure of how the data is created. Here's an example of a vanilla
8-
creature:
5+
By opening any file in the /res/cardsfolder folder you can see the basic structure of how the data is created.<br>
6+
Here's an example of a vanilla creature:
97

108
```
119
Name:Vanilla Creature
1210
ManaCost:2 G
1311
Types:Creature Beast
14-
Text:no text
1512
PT:2/2
13+
Oracle:
1614
```
1715

18-
The name of this card is Vanilla Creature. It's casting cost is 2G. It
19-
has the types Creature and Beast. It will not display any additional
20-
text in the card's template. It has a Power-Toughness of 2/2. The text
21-
line appears only if any rules printed on card are not backed by
22-
abilities defined for the given card (in most cases presence of Text
23-
line means such abilities are hardcoded).
16+
The name of this card is Vanilla Creature.<br>
17+
It's casting cost is {2}{G}.<br>
18+
It has the types Creature and Beast.<br>
19+
It has a Power-Toughness of 2/2.<br>
20+
It will not display any additional text in the card's template.<br>
2421

2522
If a card has two faces, use AlternateMode:{CardStateName} in the front face and separate both by a new line with the text "ALTERNATE".
2623

27-
There are a few other Parameters that will appear in most, if not all, cards. These are
24+
There are a few other properties that will appear in many cards. These are
2825

2926
| Property | Description
3027
| - | -
@@ -33,8 +30,8 @@ There are a few other Parameters that will appear in most, if not all, cards. Th
3330
|`Colors`|Color(s) of the card<br /><br />When a card's color is determined by a color indicator rather than shards in a mana cost, this property must be defined. If no identifier is needed, this property should be omitted.<br /><br />* `Colors:red` - This is used on Kobolds of Kher Keep, which has a casting cost of {0} and requires a red indicator to make it red.<br /><br />* `Colors:red,green` - Since Arlinn, Embraced by the Moon has no casting cost (it's the back of a double-faced card), the red and green indicator must be included.
3431
|`DeckHints`|AI-related hints for a deck including this card<br /><br />To improve synergy this will increase the rank of of all other cards that share some of its DeckHints types. This helps with smoothing the selection so cards without these Entries won't be at an unfair disadvantage.<br /><br />The relevant code can be found in the [CardRanker](https://git.cardforge.org/core-developers/forge/-/blob/master/forge-gui/src/main/java/forge/gamemodes/limited/CardRanker.java) class.
3532
|`DeckNeeds`|This can be considered a stronger variant when the AI should not put this card into its deck unless it has whatever other type is specified. The way this works is "inverted": it will directly decrease the rank of the card unless other cards are able to satisfy its types.<br />If a card demands more than one kind of type you can reuse it:<br />`DeckNeeds:Type$Human & Type$Warrior` will only find Human Warrior compared to `DeckNeeds:Type$Human\|Warrior` which is either
36-
|`DeckHas`|specifies that the deck now has a certain ability (like, token generation or counters) so that the drafting/deckbuilding AI knows that it now meets requirements for DeckHints/DeckNeeds. This is actually very useful since many of these (such as Ability$Graveyard, Ability$Token, Ability$Counters) are not deduced by parsing the abilities, so an explicit hint is necessary. Using the other types is also supported in case the implicit parsing wouldn't find it.<br />It doesn't require exact matching to have an effect but cards that care about multiple entries for a given type will be judged higher if a card seems to provide even "more" synergy for it.<br />Example:<br />Chishiro has two abilities so `DeckHas:Ability$Token & Ability$Counters` is used, therefore score for `DeckNeeds:Ability$Token\|Counters` is increased
37-
|`K`|Keyword
33+
|`DeckHas`|specifies that the deck now has a certain ability (like, token generation or counters) so that the drafting/deckbuilding AI knows that it now meets requirements for DeckHints/DeckNeeds. This is actually very useful since many of these (such as `Ability$Graveyard, Ability$Token, Ability$Counters`) are not deduced by parsing the abilities, so an explicit hint is necessary. Using the other types is also supported in case the implicit parsing wouldn't find it.<br />It doesn't require exact matching to have an effect but cards that care about multiple entries for a given type will be judged higher if a card seems to provide even "more" synergy for it.<br />Example:<br />Chishiro has two abilities so `DeckHas:Ability$Token & Ability$Counters` is used, therefore score for `DeckNeeds:Ability$Token\|Counters` is increased
34+
|`K`|Keyword (see below)
3835
|`Loyalty`|Number of starting loyalty counters
3936
|`ManaCost`|Cost to cast the card shown in mana shards<br /><br />This property is required. It has a single parameter that is a mana cost.<br /><br />* `ManaCost:no cost` for cards that cannot be cast<br />* `ManaCost:1 W W` sets the casting cost to {1}{W}{W}
4037
|`Name`|Name of the card<br /><br />A string of text that serves as the name of the card. Note that the registered trademark symbol cannot be included, and this property must have at least one character.<br /><br />Example:<br />* `Name:A Display of My Dark Power` sets the card's name to "A Display of My Dark Power"
@@ -49,95 +46,21 @@ There are a few other Parameters that will appear in most, if not all, cards. Th
4946

5047
Rarity and Set info are now defined in edition definition files. These can be found at /res/reditions path.
5148

52-
## General SVars
49+
## Conventions
50+
- filename: all lowercase, skip special characters, underscore for spaces
51+
- Unix(LF) line endings
52+
- use empty lines only when separating multiple faces on a card
53+
- try to avoid writing default params to keep scripts concise
54+
- e.g. just `SP$ Draw` instead of `SP$ Draw | Defined$ You | NumCards$ 1`
5355

54-
`SVar:SoundEffect:goblinpolkaband.mp3`
55-
56-
The sound system supports a special SVar that defines the sound that should be played when the spell is cast.
57-
58-
`SVar:AltCost:[cost]`
59-
60-
This SVar is for cards that have an Alternate cost, such as Force of
61-
Will. You are allowed to pay the Alternate Cost instead of the normal
62-
Mana cost when casting this spell.
63-
64-
`SVar:AIPreference:SacCost$Creature.token,Creature.cmcLE2`
65-
66-
`SVar:AntiBuffedBy:[ValidCards]`
67-
68-
If a permanent with this SVar is on the battlefield under human control
69-
the AI will play the specified cards in Main1. Applicable for cards like
70-
Heart Sliver or Timid Drake.
71-
72-
`SVar:BuffedBy:[ValidCards]`
73-
74-
If a permanent with this SVar is on the battlefield under its control
75-
the AI will play the specified cards in Main1. Applicable for creatures
76-
with a P/T setting static ability (Kithkin Rabble) or additional buffes
77-
(Radiant, Archangel).
78-
79-
`SVar:EnchantMe:[Multiple]/[Once]`
80-
81-
Creatures with "Multiple" in this SVar will always be prefered when the
82-
AI enchants (Rabid Wombat), creatures with "Once" only if they are not
83-
enchanted already (Gate Hound).
84-
85-
`SVar:EquipMe:[Multiple]/[Once]`
86-
87-
Creatures with "Multiple" in this SVar will always be prefered when the
88-
AI equippes (Myr Adapter), creatures with "Once" only if they are not
89-
equipped already (Kor Duelist).
90-
91-
`SVar:AIEvaluationModifier:[ValidAmount]`
92-
93-
`SVar:EndOfTurnLeavePlay:True`
94-
95-
`SVar:maxLevel:`
96-
97-
`SVar:HasCombatEffect:True`
98-
99-
`SVar:HasAttackEffect:True`
100-
101-
`SVar:HasBlockEffect:True`
102-
103-
`SVar:MustAttack:True`
104-
105-
`SVar:MustBeBlocked:True`
106-
107-
`SVar:NeedsToPlayVar:[ValidCards]`
108-
109-
`SVar:ManaNeededToAvoidNegativeEffect:`
110-
111-
`SVar:NonStackingEffect:True`
112-
113-
`SVar:PlayMain1:TRUE/ALWAYS/OPPONENTCREATURES`
114-
115-
The AI will play cards with this SVar in its first main phase. Without other AILogic, it will usually not play any permanents without this in Main1.
116-
117-
`SVar:SacMe:[number]`
118-
119-
The AI will sacrifice these cards to pay costs. The higher the number the higher the priority. Example: Hatching Plans has SVar:SacMe:5.
120-
121-
`SVar:Targeting:Dies`
122-
123-
`SVar:UntapMe:True`
124-
125-
The AI will prioritize untapping of this card.
126-
127-
`SVar:AIUntapPreference:`
128-
129-
`SVar:X:Count$`
130-
131-
Count is our general value computation function. It's quite varied with a lot of different things it can calculate and is often being updated.
56+
# Keywords
13257

133-
## Keywords
58+
All keywords need to be prepended with "K:" to be parsed correctly. Each keyword must appear on a separate line.
13459

135-
All keywords need to be prepended with "K:" to be parsed correctly. Each
136-
keyword must appear on a separate line.
60+
## Keywords without Parameters
13761

138-
### Keywords without Parameters
139-
140-
This section is for Keywords that require no additional parameters and are one or two words long. Most of these you would see exactly on cards in the game.
62+
This section is for Keywords that require no additional parameters and are one or two words long. Most of these you would see exactly on cards in the game.<br>
63+
Examples:
14164

14265
- Cascade
14366
- Changeling
@@ -201,7 +124,7 @@ This section is for Keywords that require no additional parameters and are one o
201124
- Vigilance
202125
- Wither
203126

204-
### Keywords with parameters
127+
## Keywords with parameters
205128

206129
- Adapt:{cost}
207130
- AdjustLandPlays:{params}
@@ -272,10 +195,11 @@ This section is for Keywords that require no additional parameters and are one o
272195
- UpkeepCost:{cost}
273196
- Vanishing:{TimeCounters}
274197

275-
### Longer Card Properties
198+
## Plaintext keywords
276199

277-
Plaintext properties/triggers. This section is for Keywords that are two
278-
words or longer. CARDNAME is replaced by the card's name.
200+
These are hardcoded but not truly keywords rules-wise and will eventually be turned into static abilities.
201+
Only listing the most common ones here so you can recognize them.
202+
CARDNAME is replaced by the card's name ingame.
279203

280204
- All creatures able to block CARDNAME do so.
281205
- CARDNAME assigns no combat damage
@@ -352,10 +276,81 @@ words or longer. CARDNAME is replaced by the card's name.
352276
- You may have CARDNAME assign its combat damage as though it weren't blocked.
353277
- Your life total can't change.
354278

355-
## Developer Mode
279+
# General SVars
280+
281+
`SVar:SoundEffect:goblinpolkaband.mp3`
282+
283+
The sound system supports a special SVar that defines the sound that should be played when the spell is cast.
284+
285+
`SVar:X:Count$`
286+
287+
Count is our general value computation function. It's quite varied with a lot of different things it can calculate and is often being updated.
288+
289+
# AI specific SVars
356290

357-
[Forge\_DevMode](Forge_DevMode "wikilink")
291+
`SVar:AIPreference:SacCost$Creature.token,Creature.cmcLE2`
292+
293+
`SVar:AntiBuffedBy:[ValidCards]`
294+
295+
If a permanent with this SVar is on the battlefield under human control
296+
the AI will play the specified cards in Main1. Applicable for cards like
297+
Heart Sliver or Timid Drake.
298+
299+
`SVar:BuffedBy:[ValidCards]`
358300

359-
## Remaining Cards
301+
If a permanent with this SVar is on the battlefield under its control
302+
the AI will play the specified cards in Main1. Applicable for creatures
303+
with a P/T setting static ability (Kithkin Rabble) or additional buffes
304+
(Radiant, Archangel).
305+
306+
`SVar:EnchantMe:[Multiple]/[Once]`
307+
308+
Creatures with "Multiple" in this SVar will always be prefered when the
309+
AI enchants (Rabid Wombat), creatures with "Once" only if they are not
310+
enchanted already (Gate Hound).
311+
312+
`SVar:EquipMe:[Multiple]/[Once]`
313+
314+
Creatures with "Multiple" in this SVar will always be prefered when the
315+
AI equippes (Myr Adapter), creatures with "Once" only if they are not
316+
equipped already (Kor Duelist).
317+
318+
`SVar:AIEvaluationModifier:[ValidAmount]`
319+
320+
`SVar:EndOfTurnLeavePlay:True`
321+
322+
`SVar:maxLevel:`
323+
324+
`SVar:HasCombatEffect:True`
325+
326+
`SVar:HasAttackEffect:True`
327+
328+
`SVar:HasBlockEffect:True`
329+
330+
`SVar:MustAttack:True`
331+
332+
`SVar:MustBeBlocked:True`
333+
334+
`SVar:NeedsToPlayVar:[ValidCards]`
335+
336+
`SVar:ManaNeededToAvoidNegativeEffect:`
337+
338+
`SVar:NonStackingEffect:True`
339+
340+
`SVar:PlayMain1:TRUE/ALWAYS/OPPONENTCREATURES`
341+
342+
The AI will play cards with this SVar in its first main phase. Without other AILogic, it will usually not play any permanents without this in Main1.
343+
344+
`SVar:SacMe:[number]`
345+
346+
The AI will sacrifice these cards to pay costs. The higher the number the higher the priority. Example: Hatching Plans has SVar:SacMe:5.
347+
348+
`SVar:Targeting:Dies`
349+
350+
`SVar:UntapMe:True`
351+
352+
The AI will prioritize untapping of this card.
353+
354+
`SVar:AIUntapPreference:`
360355

361-
<https://docs.google.com/spreadsheet/ccc?key=0Aipjpk0ZcU8fdFlMczZRR2tmazZGSGZYeDh1Z24teVE&usp=sharing>
356+
`SVar:NoZeroToughnessAI:True`

docs/Console-and-cheats.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Forge provides an in-game console in adventure mode.
2+
3+
You can access (and close) the console while exploring by pressing F9 (or Fn-F9).
4+
5+
To scroll the console window, click and drag the text box.
6+
7+
## Available commands
8+
9+
| Command Example | Description |
10+
| -- | -- |
11+
| resetMapQuests | Resets the map quests, resulting in all side-quest progress being lost and all side-quest types being re-picked |
12+
| give gold 1000 | Give 1000 gold |
13+
| give shards 1000 | Give 1000 shards |
14+
| give print lea 232 | Add an alpha (LEA set code) black lotus (232 collector number) |
15+
| give item <item name or code?> | Adds an in game item such as leather boots |
16+
| give set sld | Give 4 copies of every card in the Secret Lair Drop (set code SLD), flagged as having no sell value |
17+
| give nosell card forest | Gives a forest with no sell value |
18+
| give boosters leb | Add a booster from beta (LEB set code) |
19+
| give quest 123 | Add the quest by its number ID |
20+
| give life 10 | Add 10 life to yourself |
21+
| give card forest | Adds a forest to your inventory |
22+
| debug collision | Displays bounding boxes around entities |
23+
| debug map | TODO |
24+
| debug off | Turns off previously enable debugging |
25+
| teleport to 6000 5000 | Moves you 6000 tiles east and 5000 tiles north from the left bottom corner |
26+
| fullHeal | Returns your health back to baseline |
27+
| sprint 100 | Increases your speed for 100 seconds |
28+
| setColorId R | Sets the player color identity; Probably used for testing and shops |
29+
| clearnosell | Clears the no sell value flag from all cards you own that are not used in a deck |
30+
| remove enemy abc | Remove the enemy from the map with the map ID abc |
31+
| remove enemy all | Remove all the enemies from the map |
32+
| dumpEnemyDeckList | Print the enemy deck lists to terminal output stream |
33+
| getShards amount 100 | Similar to give shards command; Gives 100 shards to the player |
34+
| resetQuests | Resets the world quests. In progress quests are not abandonned or reset including dungeons. Does not reroll abandoned quests. Not really sure what this does. |
35+
| hide 100 | Enemies do not chase you for 100 seconds |
36+
| fly 100 | You can walk over obstacles for 100 seconds |
37+
| crack | Cracks a random item you are wearing |
38+
| spawn enemy Sliver | Spawns a Sliver on your screen |
39+
| listPOI | Prints all locations in terminal output stream as ID-type pairings |
40+
| leave | Gets you out of the current town/dungeon/cave |
41+
| dumpEnemyColorIdentity | Prints all enemies, their colour affinity and deck name to terminal output |
42+
| heal | Recover your full health |
43+
| dumpEnemyDeckColors | Prints all decks available to enemies and their affinities |

docs/Currency.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
There are many currencies in the game, and most of them can be interchanged.
2+
3+
# Cards
4+
5+
Acquired by:
6+
- World drops
7+
- Match reward
8+
- Draft wins
9+
- Shop purchases
10+
- Quests
11+
12+
Spent on:
13+
- Selling to shops
14+
15+
# Gold
16+
17+
Acquired by:
18+
- World drop
19+
- Match reward
20+
- Draft reward
21+
- Quests
22+
23+
Spent on:
24+
- Cards and items from shops
25+
- Drafts games
26+
- Crafting cards
27+
- Shards
28+
29+
# Shards
30+
31+
Acquired by
32+
- World drop
33+
- Quest reward
34+
35+
Spent on
36+
- Crafting cards
37+
- Shop Re-rolls
38+
- Gold exchange
39+
40+
# Challenge Coins
41+
42+
Acquired by
43+
- At the start of the game
44+
45+
Spent on
46+
- Drafts

docs/Deck-Building-Tips.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Adding basic lands and special arts
2+
3+
You can add lands by clicking the triple dots icon in the right top of the deck building interface.
4+
5+
Initially you only have access to jumpstart basic land arts - to get more, you need to purchase the landscape sketch books from the basic land shop (The Cartographers Guild).
6+
7+
# 40-card deck recommendation
8+
9+
40-card decks give you a much more predictable curve.
10+
11+
In a 40-card deck, each individual card has a 2.5% chance of being drawn.
12+
13+
In a 60-card deck, each individual card has a 1.6% chance of being drawn.
14+
15+
When you use a smaller deck, the significance of each individual card is much higher and will give you more predictable performance.
16+
17+
# Autosell
18+
19+
When you click a card that is not part of any decks, you get the option to move it to auto-sell.
20+
21+
The numbers in the interface indicate how many copies you have.
22+
23+
To sell the cards you have marked, go to any town and enter the Inn.
24+
In the Inn, the middle icon of the coin called Sell (E) will sell all your cards you have marked to sell.
25+
26+
Individual card values vary by rarity and reputation with the town you sell them in.
27+
28+
Since dying will cause you to lose a percentage of your gold, you may want to not sell all your cards immediately.

docs/Home.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
> [!CAUTION]
2-
> - if you want to contribute to this Wiki please only make pull requests against the main repos docs folder or your changes might get lost
2+
> - if you want to contribute to this Wiki please only make pull requests against the main repositories *docs* folder or your changes might get lost
33
> - due to GitHub limitations all filenames should be unique
44
55
# What is Forge?

0 commit comments

Comments
 (0)