ConfigEncoder
ConfigEncoder reads three plain-text XML inputs and writes encrypted binary blobs that the client and launcher load at startup. It is the only supported way to update connection details, client-side tunables, and launcher branding after a release has shipped - the client will not load an edited .xml.
Output files are AES-256-GCM encrypted. The per-file key is derived from the embedded master key (the same master key shared by every AXIOM-EMU binary) and the canonical lowercase filename of the blob, so the client can decrypt any bundle produced by a matching build.
Tool Location#
Tools/ConfigEncoder/
ConfigEncoder.exe
AxiomConfigEditor.exe (optional GUI)
EncoderConfig.xml
ServerConfig.xml
ClientConfig.xml
AxiomConfigEditor (optional GUI)#
AxiomConfigEditor.exe is a form editor for the same files. It opens ClientConfig.xml and ServerConfig.xml from its own folder (or use Open config folder...), and also MapFog.xml from the client's Data\Local\ (found through Output Path in EncoderConfig.xml). Save writes the XML files only. Save + Run ConfigEncoder saves and then runs ConfigEncoder.exe for you. The editor itself never encrypts anything - you can still edit the XML by hand and run ConfigEncoder yourself.
Inputs#
All three files live next to ConfigEncoder.exe and must be present for a run to succeed.
| File | Purpose |
|---|---|
EncoderConfig.xml | Tool settings: output folder, client install root, license key |
ServerConfig.xml | ConnectServer IP/port, client Serial and Version |
ClientConfig.xml | Client-side tunables - graphics, interpolation, animation timing, auto-updater, launcher branding, economy caps |
Outputs#
Written to the Output Path configured in EncoderConfig.xml (typically the client's Data\Local\ folder):
| File | Consumer | Contents |
|---|---|---|
ServerInfo.axiom | Client | ConnectServer IP/port, client serial, client version |
ClientConfig.axiom | Client | All tunables from ClientConfig.xml |
UpdateConfig.ini | Launcher | Plain text. Patch server and the server-status address. Always written |
LauncherConfig.ini | Launcher | Branding and launcher UI options (only if a <Launcher> block exists) |
The C++ servers (GameServer, DataServer, ConnectServer, JoinServer) do not read these .axiom blobs - they read their own .dat / .ini files.
UpdateConfig.ini#
ConfigEncoder writes this file on every run. The Launcher reads it (the Launcher cannot read .axiom files).
[Update]
Enabled=1 ; from <AutoUpdater Enabled>
ServerIP=... ; from <AutoUpdater ServerIP>
ServerPort=80 ; from <AutoUpdater Port>
UseHTTPS=0 ; from <AutoUpdater UseHTTPS>
[Game]
GameServerIP=... ; from ServerConfig.xml <Connection IP>
GameServerPort=... ; from ServerConfig.xml <Connection Port>
[Game] is only used for the server online/offline status shown in the Launcher.
EncoderConfig.xml#
<EncoderConfig>
<Output Path="C:\AxiomClient\Data\Local" />
<DLLIntegrity Path="C:\AxiomClient" />
<License Key="..." />
</EncoderConfig>
| Attribute | Meaning |
|---|---|
Output Path | Folder where ServerInfo.axiom / ClientConfig.axiom (and the optional .inis) are written. Point this at the client's Data\Local\ directory. |
DLLIntegrity Path | Root of the client install. ConfigEncoder computes SHA-256 hashes of the DLLs under this path and embeds them in ClientConfig.axiom for the client's integrity check at startup. |
License Key | Your portal license key. Recorded here for operator reference (the first 8 chars are printed on each run); the .axiom encryption itself uses the embedded master key, not this field. Keep it in sync with the four servers so operators don't get confused about which deployment a bundle belongs to. |
ServerConfig.xml#
<ServerConfig>
<Connection IP="1.2.3.4" Port="44405" />
<Client Serial="TbYehR2hFUPBKgZj" Version="1.04.05" />
</ServerConfig>
| Attribute | Meaning |
|---|---|
Connection IP | Public IP of your ConnectServer - the address the client connects to first. |
Connection Port | ConnectServer TCP port. Matches ConnectServerPortTCP in ConnectServer.ini. |
Client Serial | Arbitrary token. Must match ServerSerial in every GameServer's GameServerInfo - Common.dat. |
Client Version | Arbitrary version string. Must match ServerVersion in every GameServer's Common.dat. |
ClientConfig.xml#
Template for the client's runtime configuration. Each top-level block is documented inline in the shipped file. Sections actually read by ConfigEncoder:
| Block | Purpose |
|---|---|
<Graphics> | MaxFPS cap |
<Animation> | FPS-adaptive animation timing (GlobalDivisor, PlayerMultiplier, MountMultiplier, WingMultiplier, EffectBlurDivisor) |
<Interpolation> | Visual smoothing between 25Hz logic ticks (master + per-category toggles for Objects, Characters, Effects, Camera) |
<RenderingOptimization> | Chrome LOD distances and frustum culling cap |
<Frustum2D> | Terrain frustum expansion (widescreen black-corner fix) |
<GroundItems> | Ground item rendering caps and name distance |
<LootBeams> | Light beams over valuable drops (excellent, ancient, socket, jewels) |
<PostProcessing> | FXAA, bloom, motion blur, fog, SSAO toggles + tuning, wing shadow opacity |
<Economy> | Client-side zen caps (trade, warehouse, owned, personal shop) |
<AutoUpdater> | Patch server host/port/HTTPS toggle |
<TooltipColors> | Item tooltip option colors |
<Launcher> | Launcher branding (title, splash, URLs, color palette) |
<BottomUI> | Bottom hotbar scale |
<DiscordRPC> | Discord Rich Presence card shown on players' Discord profiles |
<Login> | Create Account button on the login box |
<Plugins> | Authorized client plugin DLLs, hash-locked at encode time |
<ScreenShots> | Path template for screenshot captures (folders created on demand) |
<EventTimer> | SortBySoonest — 1 (default) orders the 'H' event window dynamically (running events first, then countdowns soonest-first, then always-open, then disabled); 0 keeps the classic fixed index order |
<DLLIntegrity> | Optional <DLL Name="..." /> rows added on top of the built-in DLL list whose hashes get baked into ClientConfig.axiom |
<UI> | Skin - look of the new (AxiomUI) windows: classic (default, the vanilla look) or axiom. Old windows ignore it. An unknown or broken skin falls back to classic |
<Camera> | MaxZoomFOV - how far the mouse wheel can zoom out, in degrees (default 70, range 25-150; 35 = normal view). Higher shows more map but stretches the screen edges and costs FPS. Players' last zoom is remembered between sessions |
Every value in this file is consumed by the client only. Edit it, re-run ConfigEncoder, and the new ClientConfig.axiom replaces the previous one in Output Path.
The <ScreenShots> Path is a printf-style template that must contain exactly five integer placeholders, in order: month, day, hour, minute, per-session counter. Default:
ScreenShots\Screen(%02d_%02d-%02d_%02d)-%04d.jpg
Relative paths resolve against the client folder; absolute paths work too. Missing folders are created at capture time. A template with the wrong number or type of placeholders is rejected by the client (ConfigEncoder prints a warning) and the default is used.
The <Launcher> block also writes a plaintext LauncherConfig.ini next to the .axiom blobs. The <AutoUpdater> block goes into the plaintext UpdateConfig.ini, which is written on every run (see the UpdateConfig.ini section above). Both are read by the Launcher (not the game client).
Discord Rich Presence#
Shows a live status card on the Discord profile of every player running the client.
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
Enabled | 0 or 1 | 1 | Master toggle. 0 disables the card entirely |
ApplicationID | string | (AXIOM's) | The Discord application this card belongs to. Required when Enabled="1" |
ServerName | string | AxiomEMU Demo | Server name shown on the card |
ServerWebsite | string | (AXIOM's) | First card button. Must begin with https:// |
DiscordInviteURL | string | (AXIOM's) | Second card button. Must begin with https:// |
ImageKey | string | logo | Name of an art asset uploaded to the Discord application |
ShowMap | 0 or 1 | 1 | Include the player's current map |
ShowLevel | 0 or 1 | 1 | Include the character level |
ShowResets | 0 or 1 | 1 | Include the reset count |
ShowGrandResets | 0 or 1 | 1 | Include the grand reset count |
To set this up for your own server:
- Create an application in the Discord developer portal.
- Upload your art asset there and use the name you gave it as
ImageKey. - Copy the application's ID into
ApplicationID.
Login box#
| Attribute | Type | Parser default | Effect |
|---|---|---|---|
CreateAccountButton | 0 or 1 | 0 | Shows a Create Account button under the login box |
CreateAccountURL | string | (empty) | Opened in the player's default browser when that button is clicked |
CreateAccountURL must begin with http:// or https://; anything else suppresses the button.
Cash shop#
Web pages for the Recharge and Gift buttons in the X cash shop.
<CashShop RechargeURL="https://yoursite.com/donate" GiftURL="https://yoursite.com/gift" />
| Attribute | Type | Parser default | Effect |
|---|---|---|---|
RechargeURL | string | (empty) | Opened in the player's default browser when Recharge is clicked |
GiftURL | string | (empty) | Opened in the player's default browser when Gift is clicked |
Both must begin with http:// or https://. Empty or invalid = the button shows the vanilla "not available" box.
Authorized plugins#
Optional integrity loader for client-side plugin DLLs. Each entry is one row:
<Plugins>
<Plugin Name="plugins\yours.dll" />
</Plugins>
Name is a path relative to the client folder, at most 63 characters. At most 8 entries are read. ConfigEncoder hashes each file at encode time and bakes the hash into ClientConfig.axiom.
The shipped template ships with both example rows commented out, so the loader is inert until you opt in.
Block attributes#
The shipped XML carries inline comments for these blocks. The parser defaults below are what applies when an attribute is removed - note that several differ from the value the template ships.
| Attribute | Type | Parser default | Shipped | Effect |
|---|---|---|---|---|
ChromeLOD_CloseDistance | int tiles | 2 | 3 | Within this distance, characters get full chrome and item effects |
ChromeLOD_MediumDistance | int tiles | 5 | 5 | Between close and this distance, chrome is reduced. Beyond it, ChromeLOD_FarRenderLevel applies |
ChromeLOD_FarRenderLevel | 0-2 | 0 | 0 | Chrome detail kept for distant characters. 0 = none (cheapest) |
FrustumCulling_MaxDistance | int tiles | 15 | 17 | Objects beyond this distance are culled regardless of the view frustum |
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
WidthMultiplier | float | 1.3 | Widens the terrain frustum. Raise it if widescreen resolutions show black corners |
DepthMultiplier | float | 1.5 | Extends the frustum forward |
ExtraMargin | float | 20.0 | Flat margin added on top of both multipliers |
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
MaxZenCopies | int | 10 | Cap on rendered zen piles. Extra drops still exist and are pickable, they just are not drawn |
NameMaxDistance | int tiles | 12 | Beyond this distance, dropped item names stop being drawn |
SkipChromeEffects | 0 or 1 | 1 | 1 skips chrome shine on ground items |
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
EnableFXAA | 0 or 1 | 1 | Anti-aliasing pass |
FXAA_SpanMax | float | 4.0 | Maximum blur span |
FXAA_ReduceMin | float | 0.03125 | Lower bound on edge reduction |
FXAA_ReduceMul | float | 0.25 | Edge reduction multiplier |
EnableBloom | 0 or 1 | 1 | Glow around bright effects (spells, auras, +15 glows, lava). UI is never affected. Players can turn it off with the "Glow" graphics option |
Bloom_Threshold | float | 0.72 | Brightness where glow starts. Lower = more things glow. Range 0.5 - 0.95 |
Bloom_Intensity | float | 0.45 | Glow strength. Range 0.0 - 2.0 |
Bloom_BlurPasses | int | 3 | Glow width. Each pass doubles the reach: 1 = tight rim, 3 = wide soft halo, 4 = very wide. Use 1 - 5. Values outside 1 - 10 are clamped |
EnableMotionBlur | 0 or 1 | 0 | Motion blur pass |
MotionBlur_Strength | float | 0.15 | Blur strength |
EnableFog | 0 or 1 | 1 | Height fog master switch. Fog is thicker low down and thinner on high ground. Per-map fog lives in MapFog.xml (see below) |
Fog_DensityScale | float | 1.0 | Multiplier over every map's fog Density. Turn this down if the whole game feels too hazy. Range 0.0 - 3.0 |
Fog_SkyDepth | float | 0.9999 | Depth at or above which a pixel counts as sky. Range 0.99 - 1.0 (above 1.0 or at/below 0 is corrected) |
Fog_AutoAdaptSeconds | float | 1.5 | How fast the automatic fog colour follows the screen, on maps that use AutoColor in MapFog.xml. Lower = faster. Range 0.2 - 6.0 |
Fog_EmissiveThreshold | float | 0.60 | Brightness above which a pixel counts as a glowing effect for fog purposes. Must be 0 to below 1.0 |
Fog_EmissivePreserve | float | 0.70 | How much glowing effects keep shining through the fog. 0 = fogged like everything else, 1 = not fogged. Range 0.0 - 1.0 |
EnableSSAO | 0 or 1 | 1 | Ambient occlusion: darkens creases where objects meet the ground, so monsters and items look placed instead of floating |
SSAO_Radius | float | 90.0 | Sample radius in world units (one tile is about 100). Range 30 - 250 |
SSAO_Intensity | float | 0.55 | How dark the occlusion gets. Range 0.0 - 1.0. Turn this down first if it looks smudgy |
SSAO_Bias | float | 8.0 | Raise it if flat floors show faint noise or banding. Range 2 - 30 |
SSAO_Power | float | 1.4 | Contrast of the occlusion. Higher = crisper creases. Range 0.5 - 3.0 |
SSAO_Samples | int | 12 | Taps per pixel. More = smoother and slower. Clamped to 4 - 16 |
Shadow_WingAlpha | float | 0.35 | Opacity of the wing part of a character's shadow. 1.0 = old solid black slab, 0.0 = no wing shadow. Weapons and shields always cast solid. Clamped to 0.0 - 1.0. Atlans ignores it |
Fog and SSAO need a GPU that accepts a depth texture. If it does not, they switch themselves off and the rest keeps working (the client log says "depth TEXTURE attachment rejected").
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
Enable | 0 or 1 | 1 | Master switch for loot beams. Players can also turn them off with the "Loot Beams" graphics option |
Excellent | 0 or 1 | 1 | Beam over excellent drops |
Ancient | 0 or 1 | 1 | Beam over ancient (set) drops |
Socket | 0 or 1 | 1 | Beam over drops that actually have sockets |
Jewels | 0 or 1 | 1 | Beam over jewels (Bless, Soul, Chaos, Life, Creation, Guardian, Gemstone, Harmony, refining stones, jewel packs) |
Height | float | 360 | Beam height in world units (one tile is about 100) |
Width | float | 48 | Beam width in world units |
Intensity | float | 0.8 | Brightness, 0.0 - 2.0. Beams also feed the bloom glow |
ColorExcellent | R,G,B 0-255 | 26,255,128 | Excellent beam colour |
ColorAncient | R,G,B 0-255 | 61,89,255 | Ancient beam pillar colour |
ColorAncientCore | R,G,B 0-255 | 0,255,0 | Ancient beam core colour |
ColorSocket | R,G,B 0-255 | 179,102,255 | Socket beam colour |
ColorJewel | R,G,B 0-255 | 255,204,77 | Jewel beam colour |
Ordinary drops never get a beam. An item that fits several groups uses the tooltip order: ancient, then socket, then excellent. Default colours match the item name colours.
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
MaxTradeZen | int | 4999999999 | Client-side cap on zen entered into a trade |
MaxWarehouseZen | int | 500000000000 | Cap on warehouse zen |
MaxOwnedZen | int | 100000000000 | Cap on zen a character may carry |
MaxPersonalShopPrice | int | 100000000000 | Cap on a personal shop price |
These are display and input limits only. The server enforces its own caps; set these to match or players will be able to type values the server then rejects.
| Attribute | Type | Shipped | Effect |
|---|---|---|---|
GlobalDivisor | int | 45 | Base divisor for FPS-adaptive animation timing. Lower = faster animation overall |
PlayerMultiplier | float | 1.0 | Per-category scale for player animation |
MountMultiplier | float | 1 | Per-category scale for mounts |
WingMultiplier | float | 0.8 | Per-category scale for wing flap |
EffectBlurDivisor | int | 30 | Divisor for effect trail/blur timing |
MapFog.xml (per-map fog, colour grade and bloom)#
<client folder>\Data\Local\MapFog.xml
Per-map look settings live in this plain XML file in the client folder, not in ClientConfig.xml. It is not encoded: edit it, then type $weather reload in game (or restart the client). No ConfigEncoder run is needed. AxiomConfigEditor.exe can edit it too.
<MapFog Enable="1">
<Default Density="..." Color="R,G,B" ... />
<Map Index="0" Density="..." Bloom="..." />
</MapFog>
| Element | Meaning |
|---|---|
<MapFog Enable> | 0 turns post-process fog off on every map, without re-encoding the client config |
<Default> | Values used by every map that has no <Map> row |
<Map Index="N"> | Override for map number N. Anything it does not set comes from <Default> |
Each <Default> / <Map> row can set fog (Color, AutoColor, Density, HeightFalloff, BaseHeight, MaxOpacity, SkyOpacity, StartDistance, AmbientTint), sun tint (SunColor, SunAzimuth, SunElevation, SunExponent, SunAmount), contact shadows, colour grade (Grade, GradeSharpen, GradeContrast, GradeSaturation, GradeWarmth, GradeVignette), per-map Bloom strength, the day/night cycle (DayLight, NightLight, DayLength, DayOffset) and weather (Weather, WeatherChance, WeatherLength). Every attribute is optional and explained in the comment at the top of the shipped file.
The global switches stay in ClientConfig.xml: EnableFog, Fog_DensityScale, EnableBloom and the rest of <PostProcessing>. If MapFog.xml is missing or broken, the client uses built-in values and writes a MapFog - line to its log.
Usage#
- Edit the three XML files in
Tools\ConfigEncoder\. - Run
ConfigEncoder.exefrom its own folder. It takes no command-line arguments. - The tool writes the output blobs directly into
Output Path- no manual copy.
Re-run ConfigEncoder any time you change ServerConfig.xml or ClientConfig.xml. The client reads the blobs on startup; editing the XML alone has no effect.