7.9 KiB
7.9 KiB
WZ Data Export Utility Guide
Overview
The Elixir port uses JSON files for game data instead of parsing WZ files directly. This document describes how to create a Java utility to export WZ data to JSON format.
Required Exports
1. Item Strings (priv/data/item_strings.json)
{
"2000000": "Red Potion",
"2000001": "Orange Potion",
"1002000": "Blue Bandana",
...
}
Java Source:
// Use MapleItemInformationProvider
// Iterate over all items, extract names from String.wz
2. Items (priv/data/items.json)
[
{
"item_id": 2000000,
"name": "Red Potion",
"slot_max": 100,
"price": 50.0,
"whole_price": 50,
"req_level": 0,
"tradeable": true,
"cash": false,
"recover_hp": 50,
"recover_mp": 0
},
...
]
Fields to Export:
- item_id, name, desc
- slot_max, price, whole_price
- req_level, req_job, req_str, req_dex, req_int, req_luk
- cash, tradeable, quest, time_limited
- recover_hp, recover_mp, buff_time
- meso, monster_book, mob_id
- All flags and properties
Java Source:
// MapleItemInformationProvider.getAllItems()
// Convert ItemInformation to JSON
3. Equipment (priv/data/equips.json)
[
{
"item_id": 1002000,
"str": 0,
"dex": 0,
"int": 0,
"luk": 0,
"hp": 0,
"mp": 0,
"watk": 0,
"matk": 0,
"wdef": 5,
"mdef": 5,
"acc": 0,
"avoid": 0,
"speed": 0,
"jump": 0,
"slots": 7,
"tuc": 7,
"item_level": 1
},
...
]
Fields to Export:
- All stat fields (str, dex, int, luk, hp, mp)
- Attack/defense (watk, matk, wdef, mdef)
- Accuracy/avoidance (acc, avoid)
- Movement (speed, jump)
- Upgrade slots (slots, tuc)
- All equipment properties
Java Source:
// MapleItemInformationProvider.getAllItems()
// Filter by MapleInventoryType.EQUIP
// Extract equip stats
4. Monsters (priv/data/monsters.json)
[
{
"mob_id": 100100,
"name": "Blue Snail",
"level": 1,
"hp": 50,
"mp": 0,
"exp": 3,
"physical_attack": 8,
"magic_attack": 8,
"physical_defense": 10,
"magic_defense": 10,
"accuracy": 5,
"evasion": 3,
"speed": 50,
"boss": false,
"undead": false,
"flying": false,
"skills": [],
"revives": []
},
...
]
Fields to Export:
- All stats from MapleMonsterStats
- Behavioral flags (boss, undead, flying, friendly, etc.)
- Skills, revives
- All combat properties
Java Source:
// MapleLifeFactory.getAllMonster()
// Convert MapleMonsterStats to JSON
5. NPCs (priv/data/npcs.json)
[
{
"npc_id": 1012000,
"name": "Athena Pierce",
"has_shop": false,
"shop_id": null,
"script": null
},
...
]
Java Source:
// MapleLifeFactory.getAllNPC()
// MapleNPC.npcShopIDs for shop data
6. Maps (priv/data/maps.json)
[
{
"map_id": 100000000,
"map_name": "Henesys",
"street_name": "Victoria Island",
"return_map": 100000000,
"forced_return": 100000000,
"mob_rate": 1.0,
"field_limit": 0,
"time_limit": -1,
"bgm": "Bgm04/PlayWithMe",
"portals": [
{
"id": 0,
"name": "sp",
"type": "sp",
"x": -1283,
"y": 86,
"target_map": 999999999,
"target_portal": "",
"script": null
},
{
"id": 1,
"name": "market00",
"type": "pv",
"x": -1183,
"y": 86,
"target_map": 910000000,
"target_portal": "market01",
"script": null
}
],
"footholds": [
{
"id": 1,
"x1": -1400,
"y1": 120,
"x2": -1200,
"y2": 120,
"prev": 0,
"next": 2
}
],
"top": -400,
"bottom": 300,
"left": -1600,
"right": 1200
},
...
]
Fields to Export:
- Map metadata (id, name, street_name)
- Return maps (return_map, forced_return)
- Rates (mob_rate, recovery_rate)
- Limits (field_limit, time_limit)
- All portals with full data
- All footholds with connections
- Bounds (top, bottom, left, right)
- BGM, scripts, properties
Java Source:
// MapleMapFactory.loadAllFieldTemplates()
// FieldTemplate contains all data
// Extract portals from MaplePortal
// Extract footholds from MapleFootholdTree
Implementation Guide
Create Export Utility Class
package tools;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import server.*;
import server.life.*;
import server.maps.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class WZExporter {
private static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
private static final String OUTPUT_DIR = "../odinsea-elixir/priv/data/";
public static void main(String[] args) {
System.out.println("Starting WZ data export...");
exportItemStrings();
exportItems();
exportEquips();
exportMonsters();
exportNPCs();
exportMaps();
System.out.println("Export complete!");
}
private static void exportItemStrings() {
// Implementation here
}
private static void exportItems() {
// Implementation here
}
// ... other export methods
private static void writeJson(String filename, Object data) {
try {
Path path = Paths.get(OUTPUT_DIR + filename);
Files.createDirectories(path.getParent());
String json = gson.toJson(data);
Files.write(path, json.getBytes());
System.out.println("Wrote: " + filename);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Export
- Add WZExporter.java to Java project
- Ensure all providers are loaded (items, maps, life)
- Run:
java tools.WZExporter - Check output in
../odinsea-elixir/priv/data/ - Verify JSON files are valid
- Test in Elixir by reloading data providers
Data Validation
After export, validate data:
# In Elixir IEx console
Odinsea.Game.ItemInfo.reload()
Odinsea.Game.MapFactory.reload()
Odinsea.Game.LifeFactory.reload()
# Check counts
:ets.info(:odinsea_item_cache, :size) # Should be 10000+
:ets.info(:odinsea_map_templates, :size) # Should be 1000+
:ets.info(:odinsea_monster_stats, :size) # Should be 5000+
# Test lookups
Odinsea.Game.ItemInfo.get_name(2000000) # "Red Potion"
Odinsea.Game.MapFactory.get_map_name(100000000) # "Henesys"
Odinsea.Game.LifeFactory.get_monster_name(100100) # "Blue Snail"
Performance Considerations
- Export can take 5-10 minutes for full WZ data
- JSON files will be 50-100MB total
- Consider compressing (gzip) for distribution
- ETS loading takes <1 second with JSON
- Memory usage: ~100MB for all cached data
Incremental Export
For development, export subsets:
// Export only common maps
if (mapId < 110000000 && mapId >= 100000000) {
exportMap(mapId);
}
// Export only beginner monsters
if (mobId < 9999999 && level <= 30) {
exportMonster(mobId);
}
Troubleshooting
Problem: JSON parsing fails in Elixir
- Check JSON syntax with
jqor online validator - Ensure UTF-8 encoding
- Check for special characters in names
Problem: Missing data in exports
- Verify Java providers are fully initialized
- Check for null values
- Add default values in Java export code
Problem: Export crashes or hangs
- Add try/catch around each item
- Log progress every 100 items
- Export in smaller batches
Future Improvements
-
Incremental Updates
- Track WZ file changes
- Only export modified data
- Generate diff files
-
Validation
- Schema validation
- Referential integrity checks
- Detect missing required fields
-
Compression
- GZIP JSON files
- Binary format (MessagePack)
- Reduce file sizes 80%
-
Automation
- CI/CD integration
- Auto-export on WZ updates
- Version tracking
Next Step: Create WZExporter.java in Java project and run export!