LLM Agent files
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
# AGENTS.md — 2009scape
|
||||
|
||||
Guidance for LLM agents (and humans) working in this repository. Read this first,
|
||||
then consult the deeper docs in [`docs/`](docs/) for architecture and content patterns.
|
||||
|
||||
## What this project is
|
||||
|
||||
2009scape is an **open-source MMORPG emulation server** — a from-scratch remake of
|
||||
RuneScape 2 as it existed around **build 530 / January 2009**.
|
||||
|
||||
The server speaks the original RS2 binary protocol to a matching game client. Players
|
||||
connect over TCP or (optionally) WebSocket. This repo is the **game server only** — the
|
||||
client and cache tooling live in separate projects.
|
||||
|
||||
## The single most important rule
|
||||
|
||||
> **All new contributions MUST be written in Kotlin.** Only touch the legacy Java when
|
||||
> fixing or updating existing Java code. Do not write new features in Java.
|
||||
|
||||
Everything else in this file elaborates on how to do that well.
|
||||
|
||||
## Repository layout (top level)
|
||||
|
||||
| Path | What it is |
|
||||
|------|-----------|
|
||||
| `Server/` | The game server Maven project — **almost all work happens here** |
|
||||
| `Server/src/main/core/` | Engine: networking, cache, game loop, entities, the content **API** |
|
||||
| `Server/src/main/content/` | Actual game content: quests, NPCs, minigames, skills, regions |
|
||||
| `Server/src/test/kotlin/` | JUnit 5 tests |
|
||||
| `Server/worldprops/default.conf` | TOML server configuration (log level, DB, websocket, etc.) |
|
||||
| `Server/pom.xml` | Maven build definition |
|
||||
| `Server/detekt.yml` | Kotlin static-analysis (detekt) ruleset — runs in the `verify` phase |
|
||||
| `build`, `run` | Bash helper scripts (build / build+run the server) |
|
||||
| `run-server.bat` | Windows run script |
|
||||
| `Dockerfile`, `docker-compose.yml` | Containerized server + MySQL |
|
||||
| `Proto/`, `Server/src/main/proto/` | Protobuf for the management interface |
|
||||
| `Tools/` | Cache/data editing tools (RSDataSuite, drop-table tool, JSON diff) |
|
||||
| `docs/` | Deeper docs generated for agents (see below) |
|
||||
|
||||
## Build, run, test
|
||||
|
||||
**Prerequisites:** JDK 11 (exactly — newer JDKs are not supported by this codebase),
|
||||
and for JSON data editing, the Thanos tool which needs Java 11.
|
||||
|
||||
The Maven wrapper (`Server/mvnw`) is the source of truth; the root `build`/`run` scripts
|
||||
wrap it. From the repo root:
|
||||
|
||||
```bash
|
||||
./build -g # build the server jar into builddir/server.jar
|
||||
./build -qgc # clean + build, skipping tests (-q)
|
||||
./run # incremental build, then run the server
|
||||
./run -r # force a clean rebuild, then run
|
||||
./run -t # run tests only, don't start the server
|
||||
./run -h # full option list
|
||||
```
|
||||
|
||||
Directly with Maven (equivalent, from `Server/`):
|
||||
|
||||
```bash
|
||||
sh mvnw clean # clean (also installs bundled libs from Server/libs/)
|
||||
sh mvnw package # build the fat jar (…-with-dependencies.jar)
|
||||
sh mvnw test # run the JUnit test suite
|
||||
sh mvnw verify # build + run detekt static analysis
|
||||
```
|
||||
|
||||
> If you build manually (not via the provided scripts/IntelliJ), you **must** run
|
||||
> `mvn clean` at least once first, because the clean phase installs the bundled
|
||||
> `ConstLib` and `PrimitiveExtensions` jars from `Server/libs/` into the local repo.
|
||||
|
||||
The server main class is `core.Server`. It runs headless and listens for client
|
||||
connections. By default (`use_auth = false`, `persist_accounts = false` in
|
||||
`default.conf`) **no database is required** — great for local content testing.
|
||||
|
||||
**Docker:** copy `mysql.env.example` → `mysql.env`, create `config/default.conf` from
|
||||
`Server/worldprops/default.conf`, then `docker compose up --build`.
|
||||
|
||||
## Tech stack
|
||||
|
||||
- **Kotlin 1.8.20** (primary) + legacy **Java 11** (~roughly half the files, being phased out)
|
||||
- **Maven** build; JVM target 11
|
||||
- **kotlinx-coroutines** for the pulse/worker system
|
||||
- **classgraph** for reflective plugin discovery (see below)
|
||||
- **JSON-simple** + **toml4j** for config/data, **MySQL connector** + **SQLite** for storage
|
||||
- **Java-WebSocket** for the optional browser transport
|
||||
- **JUnit 5** for tests, **detekt** for static analysis
|
||||
|
||||
## How content is wired in — the plugin/listener model
|
||||
|
||||
This is the concept an agent most needs to understand. **There is no central registry
|
||||
you edit to add content.** Instead, at startup `core.plugin.ClassScanner` reflectively
|
||||
scans the classpath (via classgraph) and instantiates every class implementing certain
|
||||
marker interfaces. You add content by creating a new class implementing the right
|
||||
interface anywhere under `src/main/content/`.
|
||||
|
||||
The core marker interface is `core.api.ContentInterface`. The important sub-interfaces:
|
||||
|
||||
| Interface | Override | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| `InteractionListener` | `defineListeners()` | React to player↔NPC/object/item/ground interactions (`on(...)`, `onUseWith(...)`, `onEquip(...)`) |
|
||||
| `InterfaceListener` | `defineInterfaceListeners()` | Handle interface/widget button clicks |
|
||||
| `Commands` | `defineCommands()` | Register `::command` chat commands, gated by `Privilege` |
|
||||
| `LoginListener` / `LogoutListener` | | Run logic on player login/logout |
|
||||
| `TickListener` | | Run logic every game tick |
|
||||
| `StartupListener` / `ShutdownListener` | | Server lifecycle hooks |
|
||||
| `PersistPlayer` / `PersistWorld` | | Serialize custom player/world data |
|
||||
| `NPCBehavior` | | Per-NPC-id AI / combat behavior |
|
||||
| `MapArea` / `ZoneBuilder` | | Define map zones and their rules |
|
||||
| `WorldEvent` | | Global scheduled/world events |
|
||||
| `ActivityPlugin` | | Minigames / activities |
|
||||
|
||||
Minimal example (`Server/src/main/content/global/skill/AttackListener.kt`):
|
||||
|
||||
```kotlin
|
||||
class AttackListener : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
on(IntType.NPC, "attack") { player, npc ->
|
||||
player.attack(npc)
|
||||
return@on true // true = interaction handled
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Almost everything a content author needs is exposed as top-level helper functions in
|
||||
`core.api.ContentAPI.kt` (e.g. `sendMessage`, `animate`, `addItem`, `getStatLevel`,
|
||||
`teleport`, `setVarp`). **Prefer these API functions over reaching directly into engine
|
||||
internals** — they are the stable, intended surface for content.
|
||||
|
||||
## Directory conventions for content
|
||||
|
||||
Put new content where similar content already lives:
|
||||
|
||||
- `content/region/<kingdom>/` — content tied to a geographic area (Misthalin, Asgarnia,
|
||||
Kandarin, Karamja, Fremennik, Morytania, Desert, Tirannwn, Wilderness, misc). This is
|
||||
by far the largest area (~850 files). Quest logic and area NPCs/dialogue go here.
|
||||
- `content/minigame/<name>/` — self-contained minigames (Barrows, Castle Wars, Pest
|
||||
Control, MTA, etc.).
|
||||
- `content/global/skill/<skill>/` — skill training logic shared across the world.
|
||||
- `content/global/handlers/` — cross-cutting item/interface/scenery handlers.
|
||||
- `content/data/` — shared data tables and enums (consumables, jewellery, quests list).
|
||||
|
||||
Item/NPC/object/animation IDs come from the `ConstLib` dependency (`org.rs09.consts`,
|
||||
bundled in `Server/libs/`). Static game data (spawns, shops, drop tables) lives in JSON
|
||||
data files loaded at runtime — edit those with the **Thanos tool** (Java 11), not by hand.
|
||||
|
||||
## Coding standards & conventions
|
||||
|
||||
- **Kotlin for anything new.** Match the style of the surrounding file.
|
||||
- Keep engine (`core/`) and content (`content/`) separate. Content depends on the API in
|
||||
`core.api`; the engine must not depend on specific content.
|
||||
- Use `ContentAPI` helpers and `colorize(...)` for player-facing messages.
|
||||
- Author-tag classes with a KDoc `@author` where the surrounding code does.
|
||||
- **detekt** runs in `mvn verify` and CI — keep new code clean against `Server/detekt.yml`.
|
||||
- Write a JUnit test under `src/test/kotlin/` when adding non-trivial logic; the suite
|
||||
has good precedent for API, exchange, and skill tests.
|
||||
- **Authenticity matters.** This is a remake targeting the real Jan-2009 game. When
|
||||
implementing behavior, match authentic RuneScape behavior of that era rather than
|
||||
inventing new mechanics.
|
||||
|
||||
## Contributing / merge requests
|
||||
|
||||
- Upstream is **GitLab**, not GitHub. Development discussion is on Discord.
|
||||
- All merge requests **must** use the default MR template
|
||||
(`.gitlab/issue_templates/Default.md`) or they will be rejected.
|
||||
- CI is defined in `.gitlab-ci.yml`.
|
||||
- License is **AGPL-3.0** and will not be changed — keep all contributions compatible.
|
||||
|
||||
## Things to be careful about (agent gotchas)
|
||||
|
||||
- **Don't switch Java versions.** JDK 11 specifically. Higher versions break the build.
|
||||
- **Don't write new Java.** New content must be Kotlin.
|
||||
- **Don't hand-edit binary/JSON game data** — use the provided tools.
|
||||
- **`mvn clean` installs bundled libs** — a fresh checkout won't compile until it's run.
|
||||
- **No DB needed for local testing** — leave `use_auth`/`persist_accounts` false locally,
|
||||
but note the config comments: both MUST be `true` in production.
|
||||
- The `build`/`run` scripts are Bash (Linux/OSX); Windows uses `run-server.bat`.
|
||||
- This repo has **no pre-existing CLAUDE.md/AGENTS.md**; the `docs/` folder here was
|
||||
authored to help agents and is not upstream canon — treat the code and README as
|
||||
ground truth if they ever disagree.
|
||||
|
||||
## Further reading
|
||||
|
||||
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — engine internals and the game loop
|
||||
- [`docs/CONTENT_GUIDE.md`](docs/CONTENT_GUIDE.md) — how to add quests, NPCs, items, commands
|
||||
- [`docs/BOT_SCRIPTING.md`](docs/BOT_SCRIPTING.md) — the player self-botting system (`::script`) and how to add new scripts
|
||||
- [`docs/SERVER_SETUP_ARCH.md`](docs/SERVER_SETUP_ARCH.md) — compile & run the server on Arch Linux and connect from a LAN PC
|
||||
- [`docs/GLOSSARY.md`](docs/GLOSSARY.md) — RuneScape/RSPS terms used throughout the code
|
||||
- `README.md` — project history, values, and full setup instructions
|
||||
Reference in New Issue
Block a user