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

Modularization #4

Open
FlorianCassayre opened this issue Mar 26, 2017 · 5 comments
Open

Modularization #4

FlorianCassayre opened this issue Mar 26, 2017 · 5 comments

Comments

@FlorianCassayre
Copy link
Member

The original structure slowly becomes depecrated, the following points need to be reconsidered:

  • Instead of having hardcoded values, a better and more scalable way would be to store all the data in an easy-to-modify file (i.e. json or xml)
  • The code is old see by yourself
  • Unit tests?
@AmauryCarrade
Copy link
Member

AmauryCarrade commented Mar 26, 2017

+1 for unit tests. Some are really easy to implement (or already implemented, like graph validity check).

@Coutume used to store the graph into a PostgreSQL database for a similar project, because there is an implementation of the Dijkstra and A* algorithms right into the database (in the form of an extension). It could be an option to investigate. JSON files would be great too. There is also specialised formats like GeoJSON, but I don't know if they are the best option for routing.

(Oh, just noticed you moved the repository to the zDevelopers org. For coherence or another reason?)

@FlorianCassayre
Copy link
Member Author

(Oh, just noticed you moved the repository to the zDevelopers org. For coherence or another reason?)

It was supposed to be so at the very begining but I noticed it wasn't.

Also, since I moved the repository I lost most of my rights (I didn't try to push though).

@AmauryCarrade
Copy link
Member

AmauryCarrade commented Mar 27, 2017

Also, since I moved the repository I lost most of my rights (I didn't try to push though).

All organization members have push access on any repository.
I made you an admin of this repo.

@AmauryCarrade
Copy link
Member

AmauryCarrade commented May 4, 2017

Ok so, some thoughts on this subject.

First of all, I definitely think we should merge ZéPS-Core and ZéPS-GUI into a single application, either in PHP (to avoid a partial GUI rewrite) or in Python (with Flask, for better performances and language—the rewrite would not be too large anyway, with a large part in unchanged JavaScript). In both cases, the path-finding performances could be a little worse than before, but remember, there is an aggressive cache policy, every path is only computed once. We could also build up some clever cache to pre-calculate popular or typical paths.

Regarding storage, the chosen option must be, in my opinion:

  • easy to update (JSON, not Java enum);
  • with all data related to one station at the same place (typically network links);
  • able to handle non-direct paths easily (removing all “hidden” stations) — this would need to rethink some parts of the dynamic map generation but it's not a problem at all, and it would allow us to better handle other paths than the Nether, e.g. the overworld Vessinque network;
  • with no duplicated data (e.g. currently the network links are all duplicated);
  • able to handle interconnected but separated networks (more on that later);
  • able to handle complex lines colors;
  • able to handle multiple totally separated networks (e.g. Vessinque and a future so-called V6).

For the last point, we could use different file names, and put all data related to one multi-words network (e.g. Vessinque) in one file. Or in one folder, if we want to split data across multiple files.

I can't help but noticing that all stations are regrouped into lines (both netherrail, with the colors, and the overworld Grandes Routes). We could use that to simplify a lot the data input, with something like this (it's only a draft) (empty keys are comments).

{
    "name": "Vessinque",

    "networks": [
        {
            "id": "netherrail",
            "name": "Netherrail",
            "world": "v5_nether",

            "is_nether": true,
            "": "Currently, the fact that the network is in a Nether world is
                 sort of hardcoded into the ZéPS GUI, with links to “overworld
                 counterpart” using coordinates multiplied by eight, or messages
                 saying to “go into the Nether” for through-overworld paths (in
                 the alternative paths recommandations). This key will allows the
                 GUI to act knowing if the network is in the Nether, or not.",

            "coordinates_factor": 0.125,
            "": "This key is the factor to apply to the coordinates to get comparable
                 coordinates accross all networks. It is by default set to 1 if the
                 world is not a Nether one, and to 0.125 if it is. This key allows
                 to customize this value, if there is another non-vanilla kind of
                 world in the server with a factor other than 1 or 0.125.
                 It's very easy to implement and lead to a simpler code regarding to
                 coordinates (by using this factor instead of a systematic test on
                 “is that network in a Nether world?”), so here it is.",

            "stations": [
                {
                    "id": "station_code_name",
                    "name": "Displayed station name",
                    "subname": "For stations with a main name and another useful one,
                                e.g. Sanctuary. Displayed in the map under the main
                                label. Can be omitted.",
                    "description": "If needed, displayed in the map balloon. Can be omitted.",

                    "coordinates": [0, 0],
                    "": "x, z or x, y, z. In a single key for the sake of input simplicity,
                         but this could be changed.",
                    "real_coordinates": [0, 0],
                    "": "This is a new key used for geolocation purposes. In the
                         current map, most coordinates are the ones of the
                         projection of the portal location on the line, not the
                         real portal location. This would be the _real_ location,
                         not used for mapping, but used to geolocate users and
                         offer the nearest station. Can be omitted.",

                    "is_hidden": false,
                    "": "Used for the few intersections without station. If omitted,
                         false.",

                    "is_main": true,
                    "": "If exists and set to true, this is considered as a main
                         station (e.g. Nouvea, Tentaclès)",

                    "has_fast_access": true,
                    "fast_access_time": 10,
                    "": "This is meant to improve the alternative paths
                         recommandations:
                         1. stations with this tag existing and set to true will
                            be tested for shorter path;
                         2. the specified time (seconds) will be addded to the
                            whole time, to take into account the time needed to,
                            e.g., type “/spawn”, go to the portal and wait for
                            teleportation."
                }
            ],

            "lines": [
                {
                    "name": "(can be left empty or removed)",
                    "color": "#rrggbb",
                    "path": [
                        "station_1",
                        "station_2",
                        {
                            "station": "station_3",
                            "path_type": "walk",
                            "path_secure": false,
                            "path_to_next": [[0, 0], [0, 0, 0], [0, 0]],
                            "": "In a line path, we can place either stations
                                 names or objects like this.

                                 Stations names will be understood as stations
                                 objects with default values, i.e. path type to
                                 rail, considered secure, and with no specific
                                 path to the next stop (i.e. direct straight line
                                 path).

                                 path_type and path_secure should be pretty
                                 straightforward.

                                 path_to_next is my answer to complicated paths:
                                 it's an array of points the line pass by until
                                 the next stop. With this we can easily have very
                                 complex paths (in the nether but also with the
                                 overworld routes, way less straight than overworld
                                 ones)."
                        },
                        "station_4"
                    ]
                }
            ]
        }
    ],
    "networks_connections": [
        {
            "networks": ["netherrail", "overworld"],
            "autoconnect_by_name": true,
            "autonnect_by_proximity": 10,
            "connections": [
                ["station_in_the_netherrail", "station_in_the_overworld"],
                ["station_in_the_netherrail", "station_in_the_overworld"],
                ["station_in_the_netherrail", "station_in_the_overworld"]
            ],
            "": "Here, connections between the networks are defined. This
                 allows to route users through all the networks defined.

                 The connections key is easy to understand: each item in
                 the array is a connection between two networks: the one
                 from the first network in the “networks” key, the other
                 from the other one.

                 The “autoconnect_by_name” option is meant to simplify
                 our work by establishing connections automatically. It
                 would connect every station with the same “id” key in both
                 networks.

                 The idea behind the “autonnect_by_proximity” is the same,
                 but with coordinates proximity in mind. It would connect
                 stations that are closed than the amount of meters given.
                 It would take into account the world types (e.g. nether vs
                 overworld), by mutiplying or dividing by eight (or other
                 value, see “coordinates_factor”) if needed."
        }
    ]
}

As you can see, in this option, a lot of data would be auto generated, to simplify the input. I think we should, if we select an option like this one, pre-compute the networks into a real graph (my eyes are mainly looking at autoconnect_by_name and autonnect_by_proximity).

The option I propose here fulfils all points of my list but the 2nd one. I think it's a reasonable compromise.

A Bukkit plugin installed on the server to generate these JSON files could be very handful (with commands to add points or stations in lines, e.g. used through @prokopyl' CommandTools plugin).

One of the hardest thing to think about if we go into this way would be how to display in the map a path going to multiple networks. In my mind, in the main map (/plan), multiple networks are shown separately, as they would be stacked up if not. I don't have any good solution for this as for now, but I'm open to suggestions.

The router should have options to only use one or some of the defined networks, so an user can say « I only want to use the overworld network ». It would have to specify into the path when networks are changed (so the GUI can tell the user when to go to the Nether, the surface, or other).

Again these are only suggestions. Opinions?


/cc @FlorianCassayre @Coutume @prokopyl.

@AmauryCarrade
Copy link
Member

AmauryCarrade commented Jun 28, 2017

@FlorianCassayre For reference, if you're still following this project, we started with @prokopyl a reimplementation of the core in Rust, based on my suggestion above. See the rust branch. Both the router and the server (for the REST API) will be in rust, in the same code base.

The Core and the GUI will not be merged, after discussion with ProkopyL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants