Install and integrate L2J
Build one type-safe ForgeportIntegration class for your Java game server
This page is for a source-based Java game server. The goal is one integration class that describes only what Forgeport cannot know about your pack: database access, password verification, character queries, live player lookups, and the pack calls that make game changes.
Install the connector
Download these files from Admin → Game Servers:
Add both JARs to the build and runtime classpath. The connector targets Java 17.
Write the smallest usable integration
Place this class in your game-server source and replace each placeholder with the equivalent API or SQL from your pack.
package com.yourpack.gameserver.portal;
import net.forgeport.connector.Bridge;
import net.forgeport.connector.Delivery;
import net.forgeport.connector.Forgeport;
import net.forgeport.connector.model.CredentialsResult;
import net.forgeport.connector.model.GameCharacter;
import net.forgeport.connector.model.GameItem;
public final class ForgeportIntegration
{
public static void start()
{
Forgeport.start(Bridge.builder()
.database(YourConnectionPool::getConnection)
.credentials((account, password) -> {
// Query the account and verify the pack's real password format.
return CredentialsResult.INVALID;
})
.characters(account -> {
// Query this account and return List<GameCharacter>.
return java.util.List.of();
})
.items(() -> YourItemTable.templates().stream()
.map(item -> new GameItem(item.id(), item.name())))
.itemDelivery((target, item) -> {
YourPlayer player = YourWorld.player(target.requiredCharacterId());
if (player == null)
return Delivery.offline();
if (!player.account().equalsIgnoreCase(target.account()))
return Delivery.invalidTarget();
if (YourItemTable.template(item.itemId()) == null)
return Delivery.invalidItem();
return Delivery.apply(() -> player.addItem(
item.itemId(), item.count(), item.enchantLevel()));
})
.playerOnlineEvents()
.build());
}
}The five registrations above power account linking, character selection, item search, item delivery, and delivery resumption after login. Registering the code automatically advertises its protocol capability; there is no capability string list to maintain.
Supply database access
.database(...) accepts a connection provider. Forgeport uses it only for its
own portal_command delivery journal. It never queries or changes your account,
character, inventory, or world tables.
The database user needs:
CREATE,SELECT,INSERT, andUPDATEonportal_command;ALTERonly when upgrading a journal created by an older connector core;- whatever separate rights your pack-specific providers need for their SQL.
Map pack data to domain objects
Pack code returns Java values, not protocol JSON. For example, a character row becomes:
new GameCharacter(
id, name, level, classId, race, sex,
online, pvpKills, pkKills, clanName)The same boundary applies to GameItem, GameSkill, CharacterSkill,
GameClan, GameSiege, and GameBoss. Forgeport validates and serializes the
result.
Return prepared deliveries
Run every safe refusal check first. If the change can proceed, return a prepared operation:
Delivery.apply(() -> packMutation)for a live-world change;Delivery.applyInTransaction(connection -> sqlMutation)for a durable, database-only entitlement;Delivery.offline(),retryable(...),refused(...), or a typed helper when the change should not run.
Forgeport validates the result, records APPLYING, runs the prepared change,
records APPLIED, and only then responds. See
Give purchased items to characters for the practical flow.
Wire lifecycle hooks
Start after the world and data tables are initialized:
ForgeportIntegration.start();After the player is fully present in the world:
Forgeport.playerOnline(player.getAccountName(), player.getObjectId());During shutdown:
Forgeport.shutdown();Verify
- Build and restart the GameServer.
- Confirm Admin → Game Servers shows Connected.
- Run Connector check.
- Link a real test account and confirm its characters appear.
- Deliver one test item online, then one while offline and log in.
For stock code placement and pack calls, use the complete aCis 409 or Mobius High Five integration.