Web page to play Granblue Fantasy Animations.
Click Here to access it.
Originally based and modified from the chinese wiki animation player, itself based on the Granblue Fantasy Gacha page preview.
Important
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)
- Python 3.11.
- Run
pip install -r requirements.txt
in a command prompt. - See requirements.txt for a list of third-party modules.
There are a few possible ways to host this project.
Tip
This is the current way I'm using to host it 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.
- Adds extra latency.
- The bandwidth cost will take effect on this 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);
}
updater.py
is used to update json/data.json
with new elements.
It's currently compatible with most characters (R, SR, SSR, Skins), summons, weapons, enemies and classes released up to today.
There are three main possible command lines:
python updater.py -run
to simply retrieve new/unindexed elements.python updater.py -update list_of__id
to manually update the specified elements, in case they got an uncap for example (You don't need to specify the character style for characters).python updater.py -download
will download all the required assets not present on disk (Only use it if you're planning to host the assets).
You can then add the following options before the ones above for more control:
-nochange
to not update thechangelog.json
recently updated element list.
And the following if you're using GBFAL:
-gbfal
followed by the url or path to GBFALdata.json
file. You can also set it tohttps://raw.githubusercontent.com/MizaGBF/GBFAL/main/json/data.json
.
It'll use the GBFAL data.json
file to update the list of backgrounds, wiki links and also classes if possible.
- 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.
The solution is to manually set exceptions inupdater.py
, in their 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 a set:set(["ID_1", "ID_2", ..., "ID_N"])
.
- Classes
Classes also requires to be hardcoded to be updated properly (inclass_lookup
andclass_ougi
, in the__init__
function).
class_lookup
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_ougi
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 -gbfal
flag should remove the needs to manually hardcore the class details.
- 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.
As another exception, the skin Honing Seeker: Nova and its upgrades also work this way, to avoid a few headhaches related to its ID.
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:
player.js
:CANVAS_SIZE
near the top. It's size of the underneath canvas, i.e. the internal resolution, if you will.view/cjs_npc_demo.js
: AlsoCANVAS_SIZE
near the top. It must be the same as inplayer.js
.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.
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.
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.