Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend rewrite: separated polygon_definitions.js into different JSON files #23

Merged
merged 6 commits into from
Mar 6, 2025

Conversation

App24
Copy link
Contributor

@App24 App24 commented Mar 6, 2025

Separated the polygon_definitions.js file into individual JSON files for each feature, for this I created an island loader that takes all the different JSON files and translates them into a single object that is then used for the map.
I made it so that the JSON file format is pretty much the same as the one that was in the polygon_definitions.js file, but removing much of the unnecessary text.

Here is an example of an island in this new format.

{
    "region": "Emerald Archipelago",
    "name": "Dragon Cliffs",
    "secret": false,
    "type": "MultiPolygon",
    "coordinates": []
}

The fields secret and type are optional, defaulting to false and Polygon by default.

Compared to the old format, it is much cleaner.

{
    "type": "Feature",
    "properties": {
        "Region": "Emerald Archipelago",
        "Name": "Dragon Cliffs",
        "SHAPE_Area": 0.00957891753368,
        "Latitude": 31.317899703979492,
        "Longitude": 4.7566399574279785
    },
    "geometry": {
        "type": "MultiPolygon",
        "coordinates": []
    },
}

Since SHAPE_Area, Latitude and Longitude are deprecated (and I didn't see them being used at all in the code), as well as the fill, fill-opacity, etc., I decided to omit these being added when translating the JSON data into the final object.

Islands are stored in assets/islands and are separated by region and rocks/cities are separated into their owns folders per region. The one thing I was unsure how to do was name the different islands, primarily the ones that have their name field empty, so I named them as the closest named island with a suffix.

Unfortunately, I was unable to make the code 100% plug and play, as JS is not able (from my best search) to list files stored on the server. So when adding new islands, it will be needed to edit the island_files list in island_loader.js to include the path to the new island.

I've also implemented a way to save and load the user's position and zoom level, so that if they reload the page they are thrown back to the default view.

P.S. It was nice finding out you are using the Coordinate Viewer mod I made, to map out the game

App24 added 2 commits March 6, 2025 16:20
… and added an island loader to load these files. also added saving the position and zoom level of the map
@App24
Copy link
Contributor Author

App24 commented Mar 6, 2025

I think the big thing to check would be if the previous map and the new one are exactly the same, from what I saw they were, but maybe I may have missed a rock here and there when moving the data from one file to another.

@MoffKalast
Copy link
Owner

Oh man that's great! I've given it a whirr and it seems like it's all there.

It was loading a bit slower than before which is probably due to all the extra file processing, but removing the old geojson script seems to have fixed most of it.

It slightly messes up my plans to keep on piling rubbish on top of the existing big blob, so I'll need to redo the new islands I've had in the works on top of these changes, but it's a problem I'm glad to have. Any future changes should be a whole lot easier now. 👍

Since SHAPE_Area, Latitude and Longitude are deprecated (and I didn't see them being used at all in the code), as well as the fill, fill-opacity, etc., I decided to omit these being added when translating the JSON data into the final object.

Yeah that's been in there since time immemorial, I'm not sure if it was ever actually used for anything. It might be a good idea to even remove the secret flag too, then we can just split the secret and nonsecret islands by loading list in island_loader.js, where it could be edited in one place pretty easily.

Unfortunately, I was unable to make the code 100% plug and play, as JS is not able (from my best search) to list files stored on the server.

Yep, we'd need that serverside and this is all static serve so this is probably the only practical way. There might be a way to have github actions runner do it somehow when deploying so we get slightly faster load times, but probably not worth the bother.

P.S. It was nice finding out you are using the Coordinate Viewer mod I made, to map out the game

Yeah thanks for making it and keeping it up to date, it's what makes a map of this accuracy even remotely possible in the first place :)

@App24
Copy link
Contributor Author

App24 commented Mar 6, 2025

Yeah that's been in there since time immemorial, I'm not sure if it was ever actually used for anything. It might be a good idea to even remove the secret flag too, then we can just split the secret and nonsecret islands by loading list in island_loader.js, where it could be edited in one place pretty easily.

Yeah, I can do this, should be easy.

@MoffKalast
Copy link
Owner

Yeah, I can do this, should be easy.

👍

Here's another suggestion for file loading, we can load and process all files in parallel with promise.all, plus secrets separately:

const secret_island_files = [
    "aestrin/rock_of_despair",

    "alankh/eleann_island",
    "alankh/cities/eleann_island_city",
    "alankh/rocks/eleann_island_rock",

    "chronos/chronos",
    "chronos/chronos_city",
    "chronos/chronos_rock",
]

async function load_islands() {
    const island_path = "assets/islands";

    const islandPromises = island_files.map(async (island_file) => {
        try {
            const data = await fetchJSON(`${island_path}/${island_file}.json`);
            if (data.type === undefined) data.type = "Polygon";
            return data;
        } catch (error) {
            console.error(error);
            return null;
        }
    });

    const secretIslandPromises = secret_island_files.map(async (secret_island_file) => {
        try {
            const data = await fetchJSON(`${island_path}/${secret_island_file}.json`);
            if (data.type === undefined) data.type = "Polygon";
            return data;
        } catch (error) {
            console.error(error);
            return null;
        }
    });

    const [islandsData, secretIslandsData] = await Promise.all([
        Promise.all(islandPromises),
        Promise.all(secretIslandPromises)
    ]);

    // Filter out failed fetches
    islands.push(...islandsData.filter(data => data !== null));
    islands_secrets.push(...secretIslandsData.filter(data => data !== null));
}
Sequential Load Time: 418.5419921875 ms
Parallel Load Time: 228.9560546875 ms

Seems to be twice as fast on my end.

…e secret islands, also fixed a potential issue due to sorting islands and cities not drawing on top of islands
@App24
Copy link
Contributor Author

App24 commented Mar 6, 2025

Yeah, will look into that

@MoffKalast
Copy link
Owner

MoffKalast commented Mar 6, 2025

stamp

Well I believe your papers are in order, we can merge. 😄 Thanks for the help.

@MoffKalast MoffKalast merged commit 194e9a4 into MoffKalast:main Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants