Control your sim from the command line. This project was born out of a desire to explore Sims 4 modding, and integrating it with other systems.
Implements a (hot reloading) TCP server mod and CLI client for controlling The Sims 4 externally. Enables automation, scripting, and AI-driven gameplay.
┌─────────────────┐ TCP/8888 ┌──────────────────┐
│ CLI Client │ ◄──────────────────────► │ Game Server │
│ (simctl) │ JSON │ (simctl.ts4script) │
└─────────────────┘ └──────────────────┘
- Server: Python mod running inside the game, hooks into EA's event system
- Client: Standalone Python CLI that sends commands and receives events
# Test connection
simctl ping
# List what the sim has
simctl list inventory
# Watch game events
simctl watch
# Do an action
simctl chain fridge cook -w # Cook from fridge, watch until donesimctl list sims # List all sims
simctl list objects [limit] # List objects on lot
simctl list inventory # List sim's inventory
simctl list careers # List available careers
simctl list lots [filter] # List available lots
simctl active # Show active sim info
simctl needs # Show sim's needs (hunger, energy, etc.)
simctl queue # Show interaction queue
simctl time # Show game time
simctl mood # Show sim's mood
simctl relationships # Show sim's relationships
simctl whims # Show sim's whims (wants)simctl do <action> [target] # Do an action by name
simctl chain <target> <actions> # Chain interactions on a target
simctl cancel # Cancel queued interactions
# Examples
simctl do eat fridge # Eat from fridge
simctl chain toilet use flush # Use toilet, then flush
simctl chain bed sleep -w # Sleep, watch until donesimctl pause # Pause game
simctl play # Normal speed
simctl fast # Speed 2
simctl fastest # Speed 3
simctl resume # Resume and watch until idlesimctl watch # Stream all game events (Ctrl+C to stop)
simctl chain <target> <action> -w # Watch events during actionEvents include: InteractionStart, InteractionComplete, MoodChange, SkillLevelChange, BuffBeganEvent, RelationshipChanged, etc.
simctl search interactions <q> # Search available interactions
simctl search objects <query> # Search objects on lot
simctl search sims <query> # Search sims by name
simctl find <object> # Find object and show its interactionssimctl list inventory # Show inventory
simctl sell <item> # Sell item by name
simctl sell all # Sell all inventory items
simctl breed <frog1> <frog2> # Breed two frogssimctl call <sim> # Phone call a sim
simctl travel <lot> # Travel to a lot
simctl career <id> # Join a career
simctl dialog # Show dialog options
simctl dialog <n> # Select dialog optionThe chain command queues multiple interactions and can watch for completion:
# Basic chaining
simctl chain toilet use flush
# With watching (-w watches until idle, pauses when done)
simctl chain stove cook -w
# Speed control
simctl chain bed sleep -w -s fastest
# Named sequences (defined in shortcuts.yaml)
simctl chain fridge cook # Expands to fridge_Grab -> cookWith -w, the command:
- Sets game speed (default: normal, or use
-s) - Queues the interactions
- Streams events until sim goes idle (
stand_Passiveorsit_Passive) - Pauses the game when complete
If an interaction fails (InteractionExitedPipeline without completion), it also pauses.
Common interactions can be aliased in client/shortcuts.yaml:
shortcuts:
cook: fridge_GrabSnackAutonomously
shower: shower_TakeShower
clean: cleanup_Dishes_Aggregate
sleep: bed_Sleep
sequences:
cook:
- fridge_Grab
- counter_PrepareFoodThe server hooks into EA's TestEvent system to broadcast:
InteractionStart/InteractionComplete/InteractionExitedPipelineMoodChange,BuffBeganEventSkillLevelChangeRelationshipChangedWhimCompleted
Events are streamed as newline-delimited JSON over the watch connection.
In-game, you can call simctl.reload in the cheat menu (CTRL+ALT+C to open).
This allows changes to the server code to be reloaded at runtime without a game restart, but there is some minimal wrapper code around that which still requires a game reload to change.
simctl raw reload # Reload handlers/events from sourceThis reloads Python modules from src/scripts/simctl/ without restarting the game. The __init__.py (entry point) requires a full game restart.
src/scripts/simctl/
├── __init__.py # Entry point, zone hook injection
├── simctl_server.py # TCP server, non-blocking via selectors
├── handlers.py # Command handlers (get_sims, push_interaction, etc.)
├── events.py # Event broadcasting, EA event hooks
├── commands.py # In-game cheat console commands
└── reloadtest.py # Hot reload test module
client/
├── simctl # CLI client (Python)
└── shortcuts.yaml # Interaction shortcuts and sequences
make build # Compile and package to simctl.ts4script- Game console:
[simctl] ...messages - Log file:
user-data/simctl.log
- The Sims 4 (base game)
- Python 3.7+ (for client)
- Game running (server runs inside the game)
The game's Python scripts are compiled to .pyc and stored in zip archives. To understand the game's internals:
On Linux with Steam/Proton:
| What | Path |
|---|---|
| Game install | ~/.local/share/Steam/steamapps/common/The Sims 4/ |
| Game scripts | <game>/Data/Simulation/Gameplay/*.zip |
| Proton prefix | ~/.local/share/Steam/steamapps/compatdata/1222670/pfx/ |
| User data | <proton>/drive_c/users/steamuser/Documents/Electronic Arts/The Sims 4/ |
| Mods folder | <user-data>/Mods/ |
This project uses a symlink for convenience:
ln -s ~/.local/share/Steam/steamapps/compatdata/1222670/pfx/drive_c/users/steamuser/Documents/Electronic\ Arts/The\ Sims\ 4 user-dataGAME="$HOME/.local/share/Steam/steamapps/common/The Sims 4"
cd decompiled
unzip "$GAME/Data/Simulation/Gameplay/simulation.zip" -d simulation
unzip "$GAME/Data/Simulation/Gameplay/core.zip" -d core
unzip "$GAME/Data/Simulation/Gameplay/base.zip" -d base# Decompile all .pyc files (uses uncompyle6 → decompyle3 → unpyc37 fallback)
python tools/decompile.py
# Decompile a specific subfolder (faster for targeted work)
python tools/decompile.py simulation
# Control parallelism
python tools/decompile.py -j 4 simulationThe decompiler tries multiple backends in order and handles timeouts for problematic files.
decompiled/
├── base/ # Base game utilities
├── core/ # Core engine (sims4.*)
├── generated/ # Generated tuning classes
└── simulation/ # Game logic (interactions, objects, sims, etc.)
├── interactions/
├── objects/
├── sims/
└── ...
Key areas for mod development:
simulation/interactions/- How interactions worksimulation/objects/- Object components and behaviorssimulation/sims/- Sim info, needs, skillscore/sims4/commands.py- Cheat console command registration
# Build and deploy to Mods folder
python tools/build.py simctl
# Build without deploying
python tools/build.py simctl --no-deploy
# Deploy .py source files (for hot-reload development)
python tools/build.py simctl --sourceThe build script:
- Compiles
.pyto.pyc(or copies source with--source) - Packages into a
.ts4script(zip) file - Copies to
user-data/Mods/
SETUP.md- Development environment setupclient/shortcuts.yaml- Customize shortcuts
