Quick start
Steps 1–3 are for the host developer who builds the game server. If your build already ships the adapter, skip to step 4.
1. Add the dependencies
Section titled “1. Add the dependencies”All modules are in the maven-oss repository under the group app.l2nx. Reading needs no login. Other dependencies
stay on Maven Central. Each module has its own version: take the latest one from
maven-oss or the changelog and put it in place of X.Y.Z. The repository keeps the
10 latest releases of each module.
A game server needs the core, the schema migrator and Liquibase 5. Sync modules are added as needed (see modules).
repositories { exclusiveContent { forRepository { maven { name = "l2nx" url = uri("https://artifacts.l2nx.online/repository/maven-oss/") } } filter { includeGroupAndSubgroups("app.l2nx") } } mavenCentral()}
dependencies { implementation("app.l2nx:nx-gs-adapter-core:X.Y.Z") runtimeOnly("app.l2nx:nx-gs-db-migrator-liquibase5:X.Y.Z") runtimeOnly("org.liquibase:liquibase-core:5.0.4")
// Optional: only the sync modules the server uses runtimeOnly("app.l2nx:nx-gs-db-sync-core:X.Y.Z") runtimeOnly("app.l2nx:nx-gs-runtime-sync-core:X.Y.Z") runtimeOnly("app.l2nx:nx-gs-gd-sync-core:X.Y.Z")}<repositories> <repository> <id>l2nx</id> <url>https://artifacts.l2nx.online/repository/maven-oss/</url> </repository></repositories>
<dependency> <groupId>app.l2nx</groupId> <artifactId>nx-gs-adapter-core</artifactId> <version>X.Y.Z</version></dependency><dependency> <groupId>app.l2nx</groupId> <artifactId>nx-gs-db-migrator-liquibase5</artifactId> <version>X.Y.Z</version> <scope>runtime</scope></dependency><dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>5.0.4</version> <scope>runtime</scope></dependency>
<!-- Optional: only the sync modules the server uses --><dependency> <groupId>app.l2nx</groupId> <artifactId>nx-gs-db-sync-core</artifactId> <version>X.Y.Z</version> <scope>runtime</scope></dependency>nx-gs-adapter-api, nx-gs-kafka and nx-gs-commons come in transitively. Any Liquibase 5.x works; the adapter is
tested against 5.0.4.
2. Register the database connection
Section titled “2. Register the database connection”The adapter borrows connections from the pool the server already has. Implement JdbcConnectionSource with a
public no-argument constructor:
package com.example.l2nx;
import app.l2nx.gs.adapter.api.spi.provider.JdbcConnectionSource;import java.sql.Connection;import java.sql.SQLException;
public final class GameDbConnectionSource implements JdbcConnectionSource {
@Override public String name() { return "game-pool"; }
@Override public Connection getConnection() throws SQLException { return GameDatabase.getInstance().getConnection(); // the server's existing pool }}and register it for ServiceLoader:
com.example.l2nx.GameDbConnectionSourceExactly one implementation must be on the classpath. Do not force connections to read-only: the adapter sets the mode it needs after each borrow.
3. Start the adapter during boot
Section titled “3. Start the adapter during boot”Call NxAdapter.start() once the database pool is up:
import app.l2nx.gs.adapter.core.NxAdapter;
NxAdapter.onStateChange(state -> log.info("L2NX adapter state: {}", state));NxAdapter.hostExecutor(gameExecutor); // runs platform commands that must execute on the game sideNxAdapter adapter = NxAdapter.start();start()returns immediately: all work runs on daemon threads, and the call never throws into the server. Problems are reported through the log and the adapter state.- Register the host executor before
start(); without it, a command handler that needs the game side fails. - On JVM shutdown the adapter stops itself through a shutdown hook. A server that halts the JVM on its own calls
adapter.shutdown()first, so queued events are delivered. - If the server reads the adapter’s
l2nx_*tables during its own boot beforestart(), it callsNxAdapter.migrateSchema()first.
4. Get a server key
Section titled “4. Get a server key”The server key (nx_sk_…) and the platform URL of your tenant are issued on request, see
getting access.
5. Create l2nx.properties
Section titled “5. Create l2nx.properties”# Master switch: without true the adapter stays DISABLEDl2nx.enabled=truel2nx.gs-key=nx_sk_...l2nx.platform-url=https://<tenant>.api.l2nx.appThe adapter looks for the configuration in this order, key by key:
- The file given by
-Dl2nx.config-file=<path>(absolute, or relative to the JVM working directory). If the property is set but the file cannot be read, the adapter fails at start instead of silently falling back. l2nx.propertiesin the JVM working directory, when-Dl2nx.config-fileis not set. A missing file is fine.- JVM system properties
-Dl2nx.<key>=<value>, only for keys the file does not set.
Environment variables are not supported. All keys and their defaults are listed in configuration.
6. Launch and check the connection
Section titled “6. Launch and check the connection”Start the server as usual:
java -Dl2nx.config-file=/etc/l2nx/adapter.properties -cp "<server classpath>" <server main class>On start the adapter prints its banner with the version, then reports the connection:
_ ____ _ ___ __| | |___ \| \ | \ \/ /| | __) | \| |\ / L2NX game-server adapter — version 0.44.0| |___ / __/| |\ |/ \|_____|_____|_| \_/_/\_\
Connect succeeded — platform handshake passedAfter Connect succeeded the adapter is ACTIVE, or DEGRADED until the Kafka broker is reachable. Other lines and
what to do about them:
| Log line | State | What to do |
|---|---|---|
L2NX adapter is disabled (l2nx.enabled=false) |
DISABLED |
Set l2nx.enabled=true. |
Adapter failed to start due to config error: … |
FAILED |
Fix the key named in the message and restart. |
Adapter schema migration failed, adapter FAILED … |
FAILED |
Check the migrator, liquibase-core 5.x, Java 17+ and the DB user rights. |
Connect IO failure: … — retrying with backoff |
REGISTERING |
Check outbound HTTPS to the platform URL. Retries run on their own. |
Connect rejected with 401 — server-key invalid (terminal) |
FAILED |
Check l2nx.gs-key. |
Connect rejected with 403 GAME_SERVER_DEACTIVATED (terminal) |
REJECTED |
The server is deactivated on the platform: contact support. |
Kafka init failed — adapter degraded: … |
DEGRADED |
Check outbound access to the Kafka broker. |
Retries after a network error or a platform-side error wait 30 s, 1 min, 2 min, then 5 min each, with ±25% jitter.
FAILED, REJECTED and CLOSED are terminal: fix the cause and restart the server.
The current state is also available in code through NxAdapter.state() and the onStateChange callback.
