FGO-Automata
FGO-Automata allows you to play Fate/GO just like writting Python Script.
注意FGO-Automata适用于国服和日服的Fate/Grand Order. PS:中文版README
更多相关资料(如演示视频)For other related materials, see Wiki
If you're playing with other versions of Fate/GO (like TW or US), you may need to remake the template images in /assets
Table of Contents
Install
Required libs: ADB, PIL, OpenCV, numpy and pytesseract
- Clone the repo:
git clone https://github.com/Meowcolm024/FGO-Automata.git
- Install ADB:
- macOS:
brew cask install android-platform-tools
- Windows:
choco install adb
- macOS:
- Install required packages:
pip install -r requirements.txt
- Install Tesseract (Required by
pytesseract
)- macOS:
brew install tesseract
- Windows: Click here
- macOS:
Setup
There are mainly 4 ways to set up FGO-Automata(as automation script):
- If you are familiar with Python, you can try to manually write the scipt. (See: References) (You can also checkout the example.py)
- If you are using Windows,(recommended) run
daemon.py(English)
ordaemoncn.py(Chinese)
or double clickconfig.bat(Chinese)
to set up the script. - If you are using macOS(or Linux), run
daemon.py(English)
ordaemoncn.py(Chinese)
to set up the script. - You can also use the FGO-Automata Script (See: FGO-Automata Script)
You can also use FGO-Automata as an API in your own project, just import the package :)
Notice
When using FGO-Automata as a automation script, notice the following things:
- Turn OFF skill confirmation(Quick Cast).
- When using
config.bat
ordemon.py
, make sure you can pass the Checkpoint within 3 turns. - Recommended: turn ON Speed Up Death Animation and 2x Speed
- Resolution requirement: 1920x1080(recommended), or other 1080p screens (
shifts
setting required)
FGO-Automata Script
Usage
- Start REPL:
python REPL.py
(Interactive environment) - Run
FGO-Automata Script
:python REPL.py [script file]
Cheatsheet
# comments start with '#'
sft=(248,0) # set shifts
ckp="assets/Qp4.png" # reset checkpoint
spt="assets/eg-sp1.png" # reset support
start # quick start
s7 # select servant skill 7
s5t1 # select servant skill 5 target 1
m1 # select master skill 1
m2t3 # select master skill 2 target 3
m3o1t2 # select Order Change: change servant 1 for servant 2
c2 # select card 2
c65 # select card 6, 5
finish # finish battle
show # show current setting
References
1. Initialization
1. Import package
from core.Automata import Automata
- First import the package
2. Setup the Class
rin = Automata("assets/checkpoint.png", "assets/qp.png")
shiki = Automata("assets/checkpoint.png", "assets/qp.png", sft=(248, 0))
ryougi = Automata("assets/checkpoint.png", "assets/qp.png", sft=(248, 0), apl=(1, "silver"))
- The first argument and the second one refer to the path of your template of checkpoint and support servant.
- For the optional param
sft
: if your screen resolution is 1920x1080, just ignore it. But if there are blues straps at the edges, it is the shift of the top left corner. For(x, y)
, x refers to the shifts in x-axis shift, y refers to y-axis shift. - For the optional param
apl
: it is a tuple of(int, str)
, the first item is number, representing how many apples will be consumed. The second one refers to the path of your template of the type of the apple (incl. Quartz). (It has the same function asset_apples
)
3. AP related (Optional)
# .set_apples(<number of the apples>, <apple type>)
shiki.set_apples(0, "silver")
- NOTICE: It will override the set apples and the counter
- If you are using it as a automation bot, you may encounter AP problem which needs to use Gold Apples.
- Notice that the function recieves 2 arguments. The first item is number, representing how many apples will be consumed. The second one refers to the type of apples (either
quatrz
,gold
,silver
,bronze
). - Explicit control flow of the action body is required! (like an infinite loop)
2. Start battle
1. Quick Start (Recommended)
# .quick_start(advance=True)
shiki.quick_start()
- If you don't need to modify your checkpoints and supports you can use this. (Then you can skip the following 4 articles)
- By default, this method will use the
Advance Support Selection
(See Advance Support Selection). But you can also turn it OFF, which use the old way, by settingadvance=False
.
2. Reset Checkpoint (Optional)
shiki.select_checkpoint("assets/checkpoint2.png") # the argument is optional
- This method is implemented in
.quick_start()
without the argument. - You can reset checkpoint image if needed.
3. Reset Support (DEPRECATED)
# start
shiki.select_support("assets/qp2.png") # the argument is optional
- NOTICE: The function of this method is replaced by
Advance Support Selection
- This method is implemented in
.quick_start()
without the argument. - You can reset support image if needed.
About support selection
It will only select the support servant in first page(the first 3 servants) if there isn't any match, it will automatically select the first support servant by default
4. Use Advance Support Selection (Optional)
rin.advance_support() # w/o any param
ryougi.advance_support(tms=5) # update time only
shiki.advance_support(spt="assets/sp3.png", tms=1)
- This is the advance support selection, it will check the first 3 support, if none matches, it will scroll down to have another check. If there is still isn't any matches, it will try to update the support list, then repeat the cycle.
- The argument
spt
is optional, you can override the original support servant. - The argument
tms
is the times the script will update the support list, default is3
.
5. Start Battle (Optional)
shiki.start_battle()
- If you did NOT use
.quick_start()
, you need to use this command to start the battle.
3. During battle
1. Select cards
# .select_cards(<list of the desired cards(in order)>)
shiki.select_cards([7])
rin.select_cards([8,6])
ryougi.select_cards([1,2,3])
- Notice this function receives a list of maximum 3 numbers. If the list is empty or has less numbers, more cards from normal cards will be selected randomly.
- For the numbers' meaning: Number 1~5 refer to the normal cards from left to right. Number 6,7,8 refer to NP cards.
- Cards will be taped in orders
Notice there are two extra commands to select cards, which are documented in the source code :)
2. Select Servant skills
# skill w/o target
# .select_servant_skill(<id of the skill>)
shiki.select_servant_skill(4)
- Notice this function receives a number.
- The number can be in the range of 1~9, each refers to the skill counted from left.
# with target Servant
# select_servant_skill(<id of the skill>, <id of the target servant>)
ryougi.select_servant_skill(2, 3)
- You can also add the second argument for the target Servant(See: Select Servants). The second argument receives a number. The number can be in the range of 1~3, each refers to the Servant counted from left.
shiki.select_servant_skill2(2, 3)
ryougi.select_servant_skill2(1, 2, 1)
- Usage:
select_servant_skill2([servant 1~3], [skill of the servant: 1~3], [target servant (optional)])
shiki.select_servant_skillM([(1,0)]) # skill 1 w/o target servants
ryougi.select_servant_skill([(2,0), (4,1)]) # skill 2 w/o target and skill 4 w/ target servant 1
- usage: see comment above.
3. Select Master skills
# skill w/o target
# .select_master_skill(<id of the skill>)
shiki.select_master_skill(2)
- Notice this function receives a number.
- The number can be in the range of 1~3, each refers to the skill counted from left.
# with target Servant
# .select_master_skill(<id of the skill>, <id of the target servant>)
ryougi.select_master_skill(1, 3)
- You can also add the second argument for target Servant(See: Select Servants). The second argument receives a number. The number can be in the range of 1~3, each refers to the Servant counted from left.
# Order Change
# .select_master_skill(<id of the skill>, <id of the first servant>, <id of the second servant>)
rin.select_master_skill(3, 1, 1)
- If the skill is Order Change, you can add the third argument(See: Change Servants). In the second and third argument, each should be a number in the range of 1~3. The second arg refers to the first 3 Servants and the third one refers to the last 3.
4. Select Servant
# .select_servant(<id of the skill>)
shiki.select_servant(1)
- NOTICE: This function has been integrated to
select_servant_skill
andselect_master_skill
, so you don't need to use it explicitly. (Besides, the reference below is still vaild.) - There are some skills in FGO have target servant, if the skill you have chosen is this kind of skill, you may need to use this function to choose the desired Servant.
- Notice this function receives a number.
- The number can be in the range of 1~3, each refers to the Servant counted from left.
5. Change Servants
# .change_servant(<id of the first servant>, <id of the second servant>)
shiki.change_servant(1, 1)
- NOTICE: This function has been integrated to
select_master_skill
, so you don't need to use it explicitly. (Besides, the reference below is still vaild.) - This function receives 2 numbers, each should be in the range of 1~3.
- The first arg refers to the first 3 Servants and the second one refers to the last 3.
4. Finish battle
# finish
shiki.finish_battle()
ryougi.finish_battle(cont=False)
- This function allows the program tap through the ending of battle.
- The arg
cont
is optional and defaults toTrue
, it will clase the conversation asking whether to continue. When set toFalse
, no action will be taken.
5. Other functions
1. Wait for a certain scene
shiki.wait("assets/checkpoint.png")
- It allows you idle the script till a certain scene
- It receives an argument of the path of the template image.
2. Tap screen
shiki.tap((100, 100), 0, 0)
- Allows to tap a certain point in the screen
- The first arg is a tuple of the coordinate
(x, y)
- The 2nd and the 3rd args are random shifts in x and y, if you don't want have any shifts, replace with
0
3. Toggle Master Skill
shiki.toggle_master_skill()
- You can use this function to turn on/off the Master skill panel.
4. Update Support List
# .update_support() -> bool
x = shiki.update_support()
- It returns
True
if the support list is successfully updated, otherwise isFalse
.
5. Battle ID related
# .get_current_battle -> int
x = shiki.get_current_battle()
- Returns the number of current battle id (like
1
,2
or3
)
# .reached_battle(target) -> bool
x = shiki.reached_battle(2)
- Receives a number of the target battle (like
2
in battle2/3
) - Returns
True
if reached elseFalse
6. Auto Battle
# use_dynamica(target)
shiki.use_dynamica(2)
- The param
target
is the target battle id. - It allows the script to run fully automatically (See: FGO-One for the basic idea and how it works)
- Do notice that
tesseract
fails frequently
The
Dynamica
will ignore Brave Chain, NP Cards and Skills
7. Reset Ckp/Spt/Sft
shiki.reset_checkpoint("assets/Qp4.png")
shiki.reset_support("assets/eg-sp1.png")
shiki.reset_shifts((0, 0))
- You can reset checkpoint/support/shift using these functions
8. Get screenshot
# .aquire_screenshot() -> str:
shiki.aquire_screenshot()
- Take a screenshot on the device and returns the path of the image.
Making Templates
Here are two examples of the template:
The template image of the support can either be an image of a Craft Essence or a Servant(You don't need to precisely cut the image like above.).
You can use the filter feature in the game to filter the crafts and use an image of a desired Servant for selection.
Notice that your template should be distinctive.
JP
To use this script for JP version, change the variant IMAGE_BASE
in the crds.py file to:
IMAGE_BASE = "assets/jp/"
Do notice that:Dynamica
doesn't support JP version so far!
Acknowledgements
Thanks
- Tsusahi for all the testing, bug fixing and more.
- Zhen-Bo for improvements in the use of
adb
. - yztxwd for enhancements in the accuracy of OCR using
pytesseract
.
TO-DO
- Advance support selection
- Battle recognition
- FGO-Automata Script
- Auto battle analysis (See: FGO-One for the idea)
- Dynamica: Brave Chain and NP card support
- Mulitple support servants
- Party selection