Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,92 @@ pre-built artifact from its GitHub Actions CI for the target OS. See `DEVELOPMEN

`lib/lurker.lua` is called on every `love.update()`. Saving any `.lua` file will
automatically reload it in the running game — no restart required during development.

---

## Cursor Cloud specific instructions

### Environment overview

Love2D v12 nightly is installed at `/opt/love2d/` with its binary at `/opt/love2d/bin/love`
(symlinked to `/usr/local/bin/love`). The shared libraries live in `/opt/love2d/lib/` and
`LD_LIBRARY_PATH` is configured in `~/.bashrc` to include that path.

The `lua-https` native module (`https.so`) must exist in the project root (`/workspace/https.so`)
for any API/network calls to work. It is built from source
([love2d/lua-https](https://github.com/love2d/lua-https)) using cmake + g++ against libcurl and
openssl. If it is missing, rebuild it:

```bash
cd /tmp && git clone --depth 1 https://github.com/love2d/lua-https.git
mkdir -p /tmp/lua-https/build && cd /tmp/lua-https/build
cmake .. -DCMAKE_CXX_COMPILER=g++ -DUSE_CURL_BACKEND=ON -DUSE_OPENSSL_BACKEND=ON
make -j$(nproc)
cp src/https.so /workspace/https.so
```

### Running the game

```bash
export LD_LIBRARY_PATH=/opt/love2d/lib:$LD_LIBRARY_PATH
love .
```

ALSA audio errors in the log are expected (no sound device in the VM) and do not affect
gameplay. `conf.lua` sets `t.window.displayindex = 2`; this works in the Cloud VM (which
has a virtual display), but on a single-monitor setup change it to `1`.

### Backend services

The game client requires two external services for full end-to-end testing:

- **World API** (Django REST) at `http://localhost:8000` — auth, users, decks, cards
- **Nakama** server at `localhost:7350` — real-time multiplayer

The backend is cloned at `/workspace/backend` and runs via Docker Compose. To start all
backend services:

```bash
cd /workspace/backend
docker compose up -d --build
```

This starts: Postgres (5432), API (8000), Nakama (7349-7351), and SeaweedFS (8333).
Migrations and `ensure_nakama_card_fdw` run automatically on API container startup
via `entrypoint.sh`.

**First-time SeaweedFS setup** (only needed once, after the containers are running):

```bash
# Create S3 credentials
docker compose exec seaweedfs-master weed shell -master=seaweedfs-master:9333 <<'EOF'
s3.configure -user=wildleague -access_key=wildleague -secret_key=wildleague-secret -buckets=cards -actions=Read,Write,List,Tagging,Admin -apply
EOF

# Seed card data + mirror images to S3
docker compose exec api python manage.py seed_default_cards

# Allow anonymous read access to card images
docker compose exec seaweedfs-master weed shell -master=seaweedfs-master:9333 <<'EOF'
s3.configure -user=anonymous -actions=Read:cards,List:cards -apply
EOF
```

**Backend tests:** `docker compose exec api python manage.py test`

Without the backend, the game launches to the server-selection screen but cannot
authenticate or enter a match.

### Linting and testing

- **Lint (game):** `luacheck .` — see `AGENTS.md` § Linting for details.
- **Tests (game):** No project-level test suite exists. Manual testing via `love .`.
- **Lint (backend):** No linter configured; follow `.editorconfig`.
- **Tests (backend):** `docker compose exec api python manage.py test` (in `/workspace/backend`).

### Docker in the Cloud VM

Docker is installed with `fuse-overlayfs` storage driver and `iptables-legacy` for
compatibility in the nested container environment. The `ubuntu` user is in the `docker`
group for non-root access. Start the daemon with `sudo dockerd &>/tmp/dockerd.log &`
if it's not already running.
Loading