> For the complete documentation index, see [llms.txt](https://axiomemu.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://axiomemu.gitbook.io/docs/joinserver/joinserver.md).

# Overview

JoinServer validates account credentials against SQL Server and coordinates player movement between GameServers. ConnectServer points clients at a GameServer; that GameServer asks JoinServer whether the account may log in.

## Role

* Authenticates account and password against the `MEMB_INFO` table
* Tracks which account is online and on which GameServer
* Issues transfer auth codes used when a player warps to a different GameServer
* Sends a periodic UDP heartbeat to ConnectServer so CS knows JS is alive
* Rejects GameServer connections whose remote IP is not whitelisted

## File Location

```
JoinServer/
├── JoinServer.exe
├── JoinServer.ini
└── AllowableIpList.txt
```

All configuration lives in the JoinServer root. There is no `Data/` subfolder.

## Configuration Files

| File                                                         | Purpose                                       |
| ------------------------------------------------------------ | --------------------------------------------- |
| [`JoinServer.ini`](/docs/joinserver/joinserver-ini.md)       | Database, ports, authentication mode, license |
| [`AllowableIpList.txt`](/docs/joinserver/allowableiplist.md) | GameServer IP whitelist                       |

## Startup Order

{% stepper %}
{% step %}

#### License activation

JoinServer reads `LicenseKey` from `JoinServer.ini` and contacts the license service. If activation fails, the process exits before any socket is opened.
{% endstep %}

{% step %}

#### Database connect

Connects to SQL Server using `JoinServerODBC`, `JoinServerUSER`, `JoinServerPASS`. If the connection fails, JoinServer stops before opening any ports.
{% endstep %}

{% step %}

#### TCP listen

Opens `JoinServerPort` for GameServer connections. Worker and queue threads for the TCP listener are spawned in this step.
{% endstep %}

{% step %}

#### UDP target resolve

Resolves `ConnectServerAddress:ConnectServerPort` for the outbound heartbeat. A bad hostname or unresolvable address fails the step and shuts JoinServer down; the actual heartbeat datagram is not sent until the one-second timer starts firing.
{% endstep %}

{% step %}

#### IP whitelist load

Reads `AllowableIpList.txt`. If this file is missing, empty, or malformed, every incoming GameServer connection is rejected.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
All four steps after license activation must succeed in order. Failure at any step leaves JoinServer idle; restart after fixing the cause.
{% endhint %}

## Dependencies

* **SQL Server** reachable via the configured ODBC DSN, with the `MEMB_INFO` schema and `WZ_*` stored procedures installed
* **ConnectServer** reachable at `ConnectServerAddress:ConnectServerPort` by UDP - see [ConnectServer](/docs/connectserver/connectserver.md)
* **GameServer** IPs listed in [`AllowableIpList.txt`](/docs/joinserver/allowableiplist.md)

## Common Issues

* **"Could not connect to database"** - verify the ODBC DSN exists on the machine running JoinServer and the credentials are valid
* **GameServer connects then drops immediately** - its remote IP is not in [`AllowableIpList.txt`](/docs/joinserver/allowableiplist.md)
* **ConnectServer shows JoinServer offline** - `ConnectServerAddress` or `ConnectServerPort` is wrong, or a firewall blocks the outbound UDP datagram from JoinServer to ConnectServer
* **Login works but map warp fails** - the transfer auth code was not consumed within 30 seconds; the account is cleared by the once-per-second disconnect sweep and the player is kicked

## Related

* [JoinServer.ini](/docs/joinserver/joinserver-ini.md) - all runtime settings
* [AllowableIpList.txt](/docs/joinserver/allowableiplist.md) - GameServer IP whitelist
* [ConnectServer](/docs/connectserver/connectserver.md) - receives the heartbeat
* [DataServer](/docs/dataserver/dataserver.md) - separate persistence path; does not talk to JoinServer
