Web page to play Granblue Fantasy Animations.
Click Here to access it.
It's composed of a single HTML page, plus the javascript, CSS and various assets.
This section will provide informations on this part of the project.
Note
The page is static and is currently hosted on Github Pages, but it can technically be hosted anywhere.
This animation player is originally based and modified from the chinese wiki animation player, itself based on the Granblue Fantasy Gacha page preview.
It can, in theory, play every animations of the game but the scope of this project has been narrowed to Characters (including their outfits), Summons, Weapons, Main characters (classes and outfits), Enemies and some Partner Characters (from events).
Note
You can ignore this part if you plan to use a CORS Proxy.
Downloaded assets are saved in the following folders, mimicking GBF folder structure:
- Manifests in
model/manifest/
- CJS animations in
cjs/
- Spritesheets in
img/sp/cjs/
- Raid backgrounds in
img/sp/raid/
(Custom backgrounds are also inside, be careful if you want to delete the folder) - Audio files in
audio/
Here's a simplified view of the file interactions:
index.js
is the page main script. This is where the page logic is handled (index, tabs, bookmarks, etc...).script.js
handles the loading.player.js
adds the player HTML and handles the various buttons/controls under the player. Those interact withview/cjs_npc_demo.js
when needed.view/cjs_npc_demo.js
is the player logic. There is one loaded instance by version (uncaps, etc...) of the element.
The following must be changed:
- In
player.js
:CANVAS_SIZE
near the top. It's size of the underneath canvas, i.e. the internal resolution, if you will. - In
view/cjs_npc_demo.js
: AlsoCANVAS_SIZE
near the top. It must be the same as inplayer.js
. - In
css/style.css
: Undercanvas-container
(The player size, what's visible on the page) andcjs-npc-demo
(Must be equal toCANVAS_SIZE
).
The project uses a more recent version of CreateJS than GBF, and must be hotfixed to work with GBF animation files properly.
It can be found in index.js
, look for hotfix_createjs
.
There is also a small change included to allow the bounding box feature.
When fetching assets from an external source (such as a Proxy), the Cross-Origin value is set to anonymous
in hotfix_createjs
.
It's automatically set if you set const LOCAL = false;
in index.js
but, if you encounter cross-origin issues with const LOCAL = true;
, this is where to look for.
Two of the JSON files in the json
folder are the core of the system:
- changelog.json is the first file loaded upon opening the page. It contains the timestamp of the last update and a list of recently updated elements.
- data.json is loaded next and contains the data used to kickstart the player for a given element.
Others JSON files are used for debug or update purpose:
- manual_constants.json contains constant values used by the Updater, loaded and set on boot. They are in this separate file for maintainability and clarity.
More JSON files not specified here might appear in this folder, for development or testing purpose.
This script is in charge of updating the JSON files.
- Python 3.13.
- Run
pip install -r requirements.txt
in a command prompt. - See requirements.txt for a list of third-party modules.
GBFAP Updater v3.11
usage: updater.py [-h] [-r] [-u UPDATE [UPDATE ...]] [-d [DOWNLOAD ...]] [-nc] [-al PATH]
Animation Updater v3.11 for GBFAP https://mizagbf.github.io/GBFAP/
options:
-h, --help show this help message and exit
primary:
main commands.
-r, --run search for new content.
-u, --update UPDATE [UPDATE ...]
update given elements.
-d, --download [DOWNLOAD ...]
download all assets. Can specific IDs. Time and Disk space consuming.
settings:
commands to alter the update behavior.
-nc, --nochange disable update of the New category of changelog.json.
-al, --gbfal PATH import data.json from GBFAL.
Tip
For an "every day" use case, you'll only need to:
Use -r
after game updates.
Use -u
for element uncaps or if an older NPC got new arts, with their IDs.
Use -d
if you're hosting the assets to download the latest ones.
Note
It's recommended to use this project in combination with GBFAL, using the -al
argument.
It's useful to auto-detect character uncaps (along with summons to some extent) and new classes.
If you don't wish to bother with keeping an up-to-date version of GBFAL, you can still use -al
with an url instead of a path.
-al https://raw.githubusercontent.com/MizaGBF/GBFAL/refs/heads/main/json/data.json
should work just fine.
There are a few possible ways to host this project.
Tip
This is the current way it's hosted on Github Pages.
With this method:
- No GBF Assets are hosted.
- A proxy server is used to work around CORS policies.
Pros:
- Requires little effort to maintain.
- Little bandwidth and space requirement for the page itself.
Cons:
- Requires an extra server to act as a CORS Proxy between the page and GBF.
- Adds extra latency as a result.
- The bandwidth cost will take effect on the CORS Proxy server.
Setup:
- Copy/Clone this repo.
- Setup your CORS Proxy of choise. Make sure its own CORS policy only allows access from your website. CORS Anywhere is an option, or you can use my custom solution, GBFCP (Be sure to modify its CORS Url).
- Change line 3 of
index.js
with the address of your proxy. - If needed, change, around the line 97 of
index.js
, the valuetestUri
. It's expected to redirect toassets/test.png
or something else. This endpoint is used to test if the Proxy is alive and must return a HTTP 200 code.
Caution
Prepare at least 30~40 GB of disk space, to be safe (I might even be underestimating it).
Pros:
- Faster and not reliant on GBF being available (It will persist even after an eventual EoS).
Cons:
- Requires lot of disk space.
- Not fully tested.
Setup:
- Copy/Clone this repo.
- Run
python updater.py -download
to download all the assets. (The script will ask you to confirm by typyingyes
). - Change line 2 of
index.js
fromconst LOCAL = false;
toconst LOCAL = true;
- If needed, change, around the line 81 of
index.js
, the various Uris.testUri
in particular must redirect toassets/test.png
or something else.
Caution
You'll need to run python updater.py -download
after every update, but it won't re-download what's already on disk.
This also means if, for whatever reason, an old file is updated on the game side, the updater won't update it.
Tip
This one is for testing or use locally on your own computer.
- Copy/Clone this repo, along GBFCP. Install the python requirements of the later.
- Change line 3 of
index.js
toconst CORS = 'http://localhost:8001/'
. - Start GBFCP with the command
python app.py -debug
to run it in local mode. - Start a server in this project folder (you can use one of the server scripts).
- Go to http://localhost:8000/ to access your local copy of GBFAP.
You can tinker with the Game
variable around the line 80 of index.js
if you need to change the path of asset types.
If you wish to remove the proxy testing mentionned above, look for the function called successLoading
in index.js
and modify it to look this way:
function successLoading(id)
{
startplayer(id);
}
- Missing animations
Some skins/characters/weapons/weapons reuse animations of another version and, as a result, don't have their own.
You'll likely get an error message to signal those (for charge attacks and attack effects, at least), during the update process.
You can manually set exceptions in json/manual_constants.json
, in the corresponding sections:
PATCHES
is for ID substitutions of certain elements (used by characters/skins). The format is"ID_CHARA_WITHOUT_OUGI" : ["ID_OUGI_BORROWED_FROM", "ID_ATTACK_BORROWED_FROM"]
.ID_SUBSTITUTE
is also for ID substitutions but on a global scope (used by characters/skins/weapons). The format is"ID_WITHOUT_ANIMATION" : "ID_WITH_ANIMATION"
.SHARED_SUMMONS
is a similar system but for summon sharing animations. They must be grouped together in:["ID_1", "ID_2", ..., "ID_N"]
.
- Classes
Classes requires to be set injson/manual_constants.json
under the following:
CLASS_LIST
requires the class main ID and a list of its secondary ID along with its proficiencies IDs.
For example,150201
anddkf
are Dark Fencer IDs. It also uses a swordsw
and daggerkn
. So the result is"150201": ["dkf_sw", "dkf_kn"],
.CLASS_WEAPON_LIST
is mostly for skins. Some skins have weapon assets for their charge attacks. Those weapons are usually not playable.
Tip
To avoid duplicates, only the first proficiency of a class is used in the player itself.
Tip
Using the -al
flag should remove the needs to manually update the class details, but this solution isn't perfect.
-
Multiple version weapons
(Currently, only the Dark Opus are affected)
Weapons with multiple versions are separated based on their uncaps. Example1040212500
,1040212500_02
and1040212500_03
.
This is due to the fact the game doesn't support two different weapons loaded at the same time on different entities. -
Unite & Fight skin
The skin Honing Seeker: Nova and its upgrades are also separated, to avoid a few headhaches related to their ID.
The related IDs must be set injson/manual_constants.json
, underUNIQUE_SKIN
.
tester.py
is used to look for specific calls in animation files, to check for crashes.- You can use one of the
server
scripts to start a Python HTTP Server and test the project locally in your web browser. Tweaks might be needed to make the asset fetching works.