#FC25 Bot Reference
File: fc25.py · Lines: 1236 · Game: EA SPORTS FC 25
#Global Variables
| Variable | Type | Description |
|---|---|---|
sio |
socketio.Client |
WebSocket client instance |
namespace |
str |
WebSocket namespace (/fc25/stream-client) |
screen_comparator |
ScreenComparator |
Screen monitoring instance |
mem |
FC25Memory |
Memory reader instance |
cl |
obs.ReqClient |
OBS WebSocket client |
match_is_started |
bool |
Whether a match is in progress |
stop_thread |
bool |
Flag to stop memory listener |
start_sequence_active |
bool |
Guard flag to prevent duplicate starts |
goals_reset_seen |
bool |
Gate: stats only sent after initial 0-0 detected |
current_home / current_away |
str |
Current team names |
home_league / away_league |
int |
League IDs |
all_95 |
bool |
Whether to enable 95 overall rating |
#Constants
#LEAGUE_MAP
LEAGUE_MAP = {
1: 'INDONESIA', 2: 'England', 3: 'Germany', 4: 'Italy',
5: 'France', 6: 'Portugal', 7: 'Spain', 8: 'Netherlands',
10: 'Arab', 11: 'Thailand', 12: 'Japan', 13: 'Korea',
14: 'China', 15: 'Australia', 16: 'Malaysia',
17: 'RestOfWorld', 18: 'Singapore', 19: 'India', 20: 'National'
}#TEAM_ALIASES
Maps full team names to OCR-friendly aliases for team selection matching.
#Functions
#print_and_emit(message, level) ACTIVE
Print message to console and emit to WebSocket server for remote logging.
| Parameter | Type | Default | Description |
|---|---|---|---|
message |
any |
— | Message to print and emit |
level |
str |
"info" |
Log level: info, error, warning, debug |
#log_to_file(message) ACTIVE
Write message to fc25.log file or print to console based on USE_LOG_FILE flag.
#focus_window_by_exact_title(title) ACTIVE
Bring the game window to the foreground using pywinauto.
| Parameter | Type | Description |
|---|---|---|
title |
str |
Window title (e.g., 'EA SPORTS FC 25') |
#on_screen_changed(screen_name, similarity) ACTIVE
Callback fired by ScreenComparator when the game screen changes state.
| Parameter | Type | Description |
|---|---|---|
screen_name |
str |
Template name or 'none' |
similarity |
float |
Match percentage (0-100) |
Handled screens: pause_screen, internet_error, confirmation_botvsbot, draw_screen, end_as_draw, finished, *_home, *_away
#random_left_arrow(evt_name) ACTIVE
Replay callback for team/league selection. Handles 4 custom events:
| Event | Action |
|---|---|
custom #1 |
Select home league + toggle 95 overall (OCR-based) |
custom #2 |
Select home team using OCR + TEAM_ALIASES |
custom #3 |
Select away league (with retry logic for stuck detection) |
custom #4 |
Select away team using OCR + TEAM_ALIASES |
#check_for_popup(evt_name) ACTIVE
Simplified popup dismissal — just presses Enter.
Note: FC24 version is more complex with pixel checking. FC25 simplified this.
#check_for_outdated_popup(evt_name) ACTIVE
Same as check_for_popup — presses Enter to dismiss.
#_stop_memory_thread_if_running(reason) ACTIVE
Gracefully stop the memory listener thread with a 10-second timeout.
| Parameter | Type | Description |
|---|---|---|
reason |
str |
Reason for stopping (logged) |
#on_end_stream() ACTIVE
Handle end of match — emit results and navigate back for next match.
#replay_events_with_timeout(filename, callback, data) ACTIVE
Play a JSON recording file, then start a 120-second timeout checker. If match hasn't started after timeout, press Escape to return to start screen and retry.
| Parameter | Type | Description |
|---|---|---|
filename |
str |
Path to JSON recording file |
callback |
callable |
Callback for custom events in recording |
data |
dict |
Original match data for retry |
#on_new_match(data) ACTIVE
WebSocket event handler for new-match. Handles full match setup including stream restart, team selection, and memory thread start.
#on_start_match(data) ACTIVE
WebSocket event handler for starting-match. Similar to on_new_match but skips stream stop.
#on_half() ACTIVE
Handle halftime — emit half event, wait 60 seconds, then resume game.
#on_pause_screen() ACTIVE
Resume from pause screen by replaying fc25-recordings/half.json.
#on_draw_screen() ACTIVE
Handle draw result — emit end-match and navigate through draw menu.
#_is_float_nan(value) INTERNAL
Check if a value is a float NaN.
#_sanitize_ball_coord(value) INTERNAL
Convert coordinate to a finite float or None (handles NaN/inf).
#memory_listener_thread() ACTIVE
Main memory reading loop running every 0.5 seconds:
- Read goals, ball position, match time
- Detect match start condition
- Auto-detect halftime if pause screen was missed
- Gate: Wait for initial 0-0 score before sending stats
- Read statistics and red cards
- Emit
match-datavia WebSocket
#on_reload_templates_hotkey() ACTIVE
F5 hotkey callback to reload screen comparator templates at runtime.
#Socket Events (Emitted)
| Event | Namespace | Payload | When |
|---|---|---|---|
waiting |
stream | {uuid, minutes} |
Bot is ready for match |
myid |
stream | {id: uuid} |
Identify device |
start-match |
stream | {uuid} |
Match detected as started |
home-away |
stream | {uuid, home, away} |
Team names confirmed |
team-full |
stream | {uuid, home, away} |
Full team data |
half |
stream | {uuid} |
Halftime detected |
end-match |
stream | {uuid, minutes} |
Match ended |
match-data |
stream | Score/stats payload | Every 0.5s during match |
log |
/logs |
{uuid, message, level, timestamp} |
Every print_and_emit call |