Architecture
Connector components, connection lifecycle, and delivery guarantees
Components
| Component | Responsibility |
|---|---|
PortalConnector | Outbound WebSocket connection, bearer authentication, handshake, heartbeat, reconnect, and message dispatch |
PortalConfig | Loads config/portal.properties and instantiates the configured bridge |
GameBridge | Pack-specific database reads, live-world access, credential operations, and grant application |
GrantResult | Reports durable success, retryable failure, permanent failure, or an ambiguous result requiring reconciliation |
The connector core uses the JDK HTTP/WebSocket client, java.util.logging,
java.util.Properties, and minimal-json. It does not import aCis or Mobius
classes.
Bridge=<fully-qualified-class> is mandatory. If the class is missing,
cannot be instantiated, or its init() method fails, the connector remains
disabled.
The GameBridge interface
public interface GameBridge
{
String[] capabilities();
default void init() {}
int onlineCount();
JsonArray listCharacters(String accountName) throws Exception;
JsonArray listRankings(String metric, int limit) throws Exception;
String verifyCredentials(String accountName, String password) throws Exception;
default String createGameAccount(String accountName, String password) throws Exception
{
return "TEMPORARY_FAILURE";
}
String unstuck(String accountName, int characterId) throws Exception;
JsonArray searchCatalog(String term, int limit);
JsonArray searchSkillCatalog(String term, int limit);
GrantResult applyGrant(String commandId, JsonObject payload);
}Implement only the methods required by the capabilities you intend to advertise. The capability reference defines each method, result, and payload.
Connection lifecycle
PortalConfig.load()readsconfig/portal.properties.PortalConnector.start()instantiates the configured bridge and runsinit().- The connector opens the configured WebSocket URL with the PortalToken as a bearer credential.
- The connector sends a protocol v1 handshake.
- Heartbeats report connection state and online-player count.
- A closed or failed connection is retried with exponential backoff from 5 to 60 seconds.
The default heartbeat interval is 15 seconds. The gateway considers a connection stale when heartbeats stop arriving.
Handshake
The protocol v1 handshake contains the game type, connector version, and advertised capabilities:
{
"gameType": "LINEAGE_2",
"adapterVersion": "0.9.0",
"capabilities": ["VERIFY_GAME_CREDENTIALS", "GET_ONLINE_COUNT", "..."]
}The protocol does not transmit pack, chronicle, or revision metadata.
adapterVersion is compared with the Forgeport connector release catalog.
Grant idempotency
applyGrant receives a stable commandId. The bridge must persist command
state before changing game state:
new command → APPLYING → APPLIEDThe reference implementations store this journal in the portal_command
table.
- A replay of
APPLIEDreturnsALREADY_APPLIED. - A transient condition such as an offline character returns
RETRYABLE_FAILURE. - Input that cannot succeed returns
PERMANENT_FAILURE. - A replay left in
APPLYINGreturnsRECONCILIATION_REQUIRED; it is not applied again automatically.
This journal is required for item delivery, skill delivery, rename, and gender change.