Model or dataset
AhmadHassan-BTed/EQAI avatar
AhmadHassan-BTed/EQAI

EQAI: transplanting old character models into a PS2 engine

A highly specialized reverse-engineering pipeline designed to structurally transplant original Vanilla character models into the EverQuest Online Adventures: Frontiers (PS2) game engine, resolving complex Vector Unit 1 (VU1) shader bugs, Emotion Engine (EE) memory overflows, and PS2 CDVDman hardware faults.

1,977 stars0 forksPythonLicense varies

At a glance

What is it?
EQIA is a Python reverse engineering pipeline that moves original EverQuest Online Adventures character geometry into the Frontiers client while keeping the runtime structures the PlayStation 2 engine expects intact. It suits people preserving old game assets, and it is a research codebase for one specific game rather than a general tool.
Who is it for?
Adopt EQAI if you are preserving or restoring original EverQuest Online Adventures character assets, because the approach of moving a whole geometry macro-node rather than splicing floats is the part that makes the result bootable, and the DMA, VIF and material audits are what catch the mistakes before an ISO is written.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 112 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The goal is geometry only, never the runtime container

EQAI is a reverse engineering pipeline by Ahmad Hassan, also credited as B-Ted, whose stated purpose is transplanting original EverQuest Online Adventures character geometry into EverQuest Online Adventures: Frontiers without breaking the PS2 engine assumptions around skeleton memory, DMA packet layout, material state or CDVD file loading.

The scope is narrow in a way that matters. The target platform is PlayStation 2 or PCSX2, the main language is Python 3.12, and the primary task is described as a geometry-only macro-node transplant. The output is a bootable patched Frontiers ISO.

The design rule is stated as a single sentence and it explains everything else in the project: preserve the structures the Frontiers engine allocates and schedules, and replace the geometry payload only after it can be moved as a whole, aligned object.

That is why the project avoids naive binary merging. The README lists what the engine is sensitive to: node order, buffer size expectations, DMA alignment, VIF packet layout, material state, and UDF and CDVD placement. Each of those is a way for a well-intentioned merge to produce an image that no longer boots, and the pipeline treats them as constraints to design around rather than as bugs to discover later.

A conservative architecture with one graft at its centre

The architecture diagram in the README traces the flow from both asset sets to a patched ISO, and the shape of it is the argument for the whole approach.

Vanilla and Frontiers CHAR.ESF and CSF files both feed a parsing step that produces matched target records. From there the flow splits. One branch extracts the Frontiers model wrapper, whose nodes are then preserved as runtime-safe. The other extracts the Vanilla geometry macro-node, which is validated for DMA and VIF payloads. The two branches rejoin at a hybrid model assembly step, and from there the CHAR.ESF payload is rebuilt, the ISO is patched in place, and the result is a bootable patched Frontiers ISO.

The split is the point. The wrapper and the payload are treated as separate objects with separate rules, and only the payload is replaced. Everything the engine schedules stays exactly where it was.

The status table records three capabilities as solved, including the invisible character fix, which preserves Frontiers render-critical material state, and the 0x0 TLB miss crash, which avoids an EE skeleton buffer overflow. DMA and VIF integrity is also solved, with the note that it moves whole geometry macro-nodes instead of splicing float arrays. In-place ISO patching is implemented, described as avoiding rebuilding layouts that break PS2 CDVD expectations.

The motivation given for all of this is stated plainly: keeping an older online world understandable, inspectable and repairable, instead of letting its formats and tooling disappear into scattered notes and one-off scripts.

Ten core modules, each auditing one failure mode

The internal module structure is a table of responsibilities, and reading it is the fastest way to understand the engineering.

The main workflow is core/clean_transplant_geom_only.py, the geometry-only macro-node transplant. Alongside it, core/repack_iso.py does in-place ISO payload replacement without destructive layout rebuilding, and core/patch_udf_char_esf_v2.py handles UDF allocation descriptor patching for updated CHAR.ESF lengths. core/validate_dma.py performs low-level DMA tag integrity checks, core/audit_materials.py does material node inspection and render-state validation, and core/w_component_audit.py verifies W component preservation including ADC bit behaviour.

The parsing side is core/esf_parser.py for binary ESF structure parsing and core/esf_rebuilder.py for rebuild support on modified ESF payloads. The diagnostics/ directory holds focused inspection scripts for offsets, trees, payloads, textures and runtime behaviour, and UTILITIES/ collects community utility repos, tools, format references and server implementations.

Read as a set, these modules map one to one onto the ways this kind of pipeline fails. A DMA tag check catches a misaligned packet. A material audit catches a render state that no longer matches the mesh. A UDF descriptor patch catches a length change that the CDVD layer would otherwise reject. A W component audit with ADC bit behaviour is the kind of detail that only matters if you have already seen the crash it prevents.

That is the difference between a script that works once and a pipeline. The audits are not decoration around the graft, they are the reason the graft is safe.

Six phases from baseline assets to a patched ISO

The patch lifecycle is documented as six phases, and the reasons column matters more than the actions.

Phase one is baseline preparation, where the required Vanilla and Frontiers assets are placed in expected folders, which keeps original and target data separated. Phase two is database parsing, inspecting ESF and CSF records and pointer tables, and it exists to prevent guesswork around offsets and payload sizes.

Phase three is structural comparison, where the Vanilla and Frontiers model trees are compared to identify what can move and what must stay native. This is the analytical step that decides the shape of the graft, and it comes before any bytes are touched.

Phase four is the macro-node graft itself, where Vanilla 0x02610 geometry is inserted into a Frontiers-safe wrapper, which preserves DMA chain integrity. Phase five is verification, auditing DMA tags, materials, skeleton assumptions and payload boundaries to catch runtime-breaking mistakes before ISO patching. Phase six is the ISO patching itself, with CHAR.ESF patched directly into the original image.

The ordering is deliberate and conservative. Verification is phase five, not a step after patching, and the in-place approach means the original disc image is never rebuilt from scratch. The data flow diagram shows the same thing at a lower level, with pointer table parsing feeding a target asset map, then separate Vanilla geometry extraction and Frontiers runtime wrapper extraction, then the DMA and VIF audit on one side and the material and skeleton retention on the other, meeting at a hybrid payload.

The repository layout follows the phases as well, with directories named phase1_patch_ingame_models, phase2_preserve_baseline, phase3_patch_character_selection and phase4_unified_patch, plus a legacy/ directory and a workspace/ directory, which suggests the history of the approach is preserved rather than flattened away.

A Windows batch entry point, a community utility base, and an MIT claim

The interface is not a Python CLI in the usual sense. The workflow diagram names a User, an ESF and CSF parser, a geometry transplant step, an in-place ISO patcher and the PCSX2 or PS2 runtime, and the tool that sits between them is EQOA_MASTER_TOOL.bat, a Windows batch file. The internal diagram adds setup_environment.bat alongside it, and the two are in the interface layer above the core.

The top level of the repository is consistent with that: EQOA_MASTER_TOOL.bat, setup_environment.bat, run_pipeline.py, iso_rip_and_render.py and pristine_structural_upgrade.py sit next to core/, diagnostics/, docs/, tools.md, assets/, iso/, legacy/, workspace/ and the four phase directories, plus a PATCH_GUIDE.md, a WALKTHROUGH_DEV.md, a CHANGELOG.md and a.gitmodules file for the UTILITIES/ submodules.

The documentation split is worth noting for anyone picking this up. PATCH_GUIDE.md and WALKTHROUGH_DEV.md are the two entry points named in the top level, and the status table says documentation is active, with architecture and workflow notes being consolidated. The internal module diagram also shows a reports node feeding the diagnostics, so the written output of an investigation is treated as a first class artifact.

On the licence, the README badge claims MIT. The repository's licence field is reported as unknown. This article does not give legal advice, and for a project of this size, the practical step is to read the licence file yourself.

The project has no GitHub releases, and the last push to the main branch was on 2026-07-03.

Editorial conclusion

Adopt EQAI if you are preserving or restoring original EverQuest Online Adventures character assets, because the approach of moving a whole geometry macro-node rather than splicing floats is the part that makes the result bootable, and the DMA, VIF and material audits are what catch the mistakes before an ISO is written. Do not adopt it as a general asset tool, since every module is written against ESF and CSF structures, UDF descriptors and PS2 DMA layout, and the pipeline expects a Windows batch entry point and a PCSX2 runtime. Before you run it, read PATCH_GUIDE.md and WALKTHROUGH_DEV.md, put the Vanilla and Frontiers assets in their expected folders so the two data sets stay separated, and check the licence yourself, since the README badge claims MIT while the repository licence is reported as unclassifiable.

Frequently asked questions

What does EQAI actually do?

It transplants original EverQuest Online Adventures character geometry into the Frontiers PS2 client. The pipeline parses ESF and CSF asset databases, extracts the Vanilla geometry macro-node and the Frontiers runtime wrapper, keeps the Frontier nodes the engine schedules, audits DMA and VIF payloads, rebuilds CHAR.ESF and patches the ISO in place to produce a bootable patched image.

Why does EQIA move whole macro-nodes instead of merging mesh data?

The stated design rule is to replace the geometry payload only after it can be moved as a whole, aligned object, because the PS2 engine is sensitive to node order, buffer size expectations, DMA alignment, VIF packet layout, material state and UDF and CDVD placement. The status table records DMA and VIF integrity as solved by moving whole geometry macro-nodes instead of splicing float arrays.

What do the core modules in the EQAI repository do?

core/clean_transplant_geom_only.py is the main geometry-only macro-node transplant workflow, core/repack_iso.py does in-place ISO payload replacement, core/patch_udf_char_esf_v2.py patches UDF allocation descriptors for updated CHAR.ESF lengths, core/validate_dma.py checks DMA tag integrity, core/audit_materials.py validates material and render state, and core/esf_parser.py parses the binary ESF structure.

How do I start working on the EQAI pipeline?

The repository ships setup_environment.bat and EQOA_MASTER_TOOL.bat as the interface layer, and PATCH_GUIDE.md and WALKTHROUGH_DEV.md as the documentation entry points. The first lifecycle phase places the required Vanilla and Frontiers assets in their expected folders so the two data sets stay separated before any parsing begins.

Official sources

  1. AhmadHassan-BTed/EQAI on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ahmadhassan-bted-eqai.svg)](https://hysenlabs.com/projects/ahmadhassan-bted-eqai)

Was this useful?