This project makes it easy to create, run, and evaluate custom agents for the card game Figgie. It includes:
- A Python Flask application serving the Figgie API
- A PostgreSQL database for event logging and analytics
- A dashboard for tracking performance
- A modular interface + dispatcher for agent development
Official Figgie implementation: https://www.figgie.com
- Requirements
- Getting Started
- Using the Dashboard
- Configuration
- Running & Testing
- Other Documentation
- Creating Your Agent
- Roadmap
- Python 3.13
- Docker Desktop 27.5+
- Docker Compose (bundled with Docker Desktop)
-
Clone the repo
git clone git@github.com:LSeaburg/FiggieServer.git cd FiggieServer -
Build and start servers, DB, and dashboard
docker compose up --build
Optionally add
-dto start in the background -
Go to
http://localhost:8050to view the dashboard
-
Clone the repo
git clone git@github.com:LSeaburg/FiggieServer.git cd FiggieServer -
(Optional) Create and activate a virtual environment
python -m venv .venv && source .venv/bin/activate
-
Install Python dependencies
pip install -r requirements-dev.txt
-
Build and start servers, DB, and dashboard
docker compose up --build
Optionally add
-dto start in the background -
Configure and run games manually by editing
agents/examples/run_sample_agents.py. Executepython agents/examples/run_sample_agents.py
to simulate a game.
-
Follow the examples inside
agents/traders/and make your own agent profile. Add an entry toagents/traders.yamlso it appears in the dashboard. -
Go to
http://localhost:8050to view the dashboard
The dashboard is based around the idea of experiments - a set of agents to repeatedly play against each other.
4 or 5 players can be configured to play against each other.
When multiple games of the experiment are simulated agents' average profits will be tracked and compared.
The polling rate defined in the agent configuration is the 'normalized polling rate', the rate it would be in a 240 second game. During simulation this rate will be adjusted if the server's TRADING_DURATION is not 240 seconds.
Note: Results from agents with the EXACT same parameters will be combined.
Currently only results between configured agents in the same experiment can be compared against each other. This is to avoid complication when agents perform differently in different environments.
Environment variables can be set in your shell or by editing docker-compose.yml:
services:
server:
environment:
- TRADING_DURATION=240 # in seconds (default: 240)Default ports:
- 4 Player Server → 5050
- 5 Player Server → 5051
- Database → 5432
- Dashboard → 8050
python -m coverage run -m pytest
python -m coverage report -m
python -m coverage htmldocker compose down -vSee figgie_server/README.md for full API spec and server internals.
See dasshboard/README.md for full specs and dashboard internals.
Examples: agents/traders/noise_trader.py, agents/traders/fundamentalist.py. Both follow the design in this paper.
agents/figgie_interface.py exposes minimal hooks and actions so you can swap in different server implementations.
Actions:
interface.bid(price: int, suit: str): Place a buy order.interface.offer(price: int, suit: str): Place a sell order.interface.buy(suit: str): Instantly buy one unit at the current best ask.interface.sell(suit: str): Instantly sell one unit at the current best bid.interface.cancel_bids_and_offers(suit: str): Cancel all your orders for a given suit.
Event hooks:
on_start(hand: Dict[str, Any], opponent_ids: Set[str]): Fired once when trading begins, with your initial hand and polling ids.on_tick(remaining_time: int): Fired every polling cycle with remaining time (seconds).on_bid(player_id: str, price: int, suit: str): Fired on new highest bids by any player.on_offer(player_id: str, price: int, suit: str): Fired on new lowest asks by any player.on_cancel(order_type: str, old_pid: str, old_price: int, new_pid: Optional[str], new_price: Optional[int], suit: str): Fired when orders are canceled or outbid.on_transaction(buyer_id: str, seller_id: str, price: int, suit: str): Fired on each completed trade.
Attributes:
player_id: ID of the agent.
Configure your agents in agents/examples/run_sample_agents.py by editing the AGENTS list:
AGENTS: List[AgentConfig] = [
AgentConfig("fundamentalist", "Fundamentalist", 1.0, {"aggression": 0.5, "buy_ratio": 1.2}),
AgentConfig("noise_trader", "NoiseTrader", 1.0, {"aggression": 0.6, "default_val": 5}),
...
]Run them:
python agents/examples/run_sample_agents.pyResults are logged to PostgreSQL for later analysis or to view in the dashboard (once available).
- Fundamentalist agent incorporating inference based on opponent bids
- Additional agents based on documented strategies
- Reinforcement-learning for building agents
- Better dashboard insights
- WebSocket server support
- Multiple rooms with per-room config
- Persistent rooms (cumulative balances)
- GUI for live game visualization