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

Signs API #100

Open
Thomas--S opened this issue Feb 28, 2018 · 8 comments
Open

Signs API #100

Thomas--S opened this issue Feb 28, 2018 · 8 comments

Comments

@Thomas--S
Copy link
Member

Thomas--S commented Feb 28, 2018

I suggest the following API for signs:

Please notice: additional fields will be added to the definition tables during development as needed.

Updated version (2018-03-06 17:49 UTC)

streets.signs.register_collection()

streets.signs.register_collection({
    name = "minetest",
    description = "Minetest-style Signs",
    info = "This signs are meant to be internationally understandable."
        .. "Blue signs are mandatory signs."
        .. "Yellow signs are danger signs."
        .. "White-red signs are prohibitory signs.",
})
  • name is an unique technical name for the collection. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the collection.
    If left blank, it will be auto-generated from the name field.
  • info is a human-readable info text of the collection.
    This field is optional.

Registered collections are stored in streets.signs.registered_collections.
streets.signs.registered_collections is structured as follows:

streets.signs.registered_collections = {
    ["minetest"] = {
        name = "minetest",
        description = "Minetest-style Signs",
        info = "This signs are meant to be internationally understandable."
            .. "Blue signs are mandatory signs."
            .. "Yellow signs are danger signs."
            .. "White-red signs are prohibitory signs.",
    }
}

streets.signs.registered_collections must not be accessed directly.
Use streets.signs.get_collection_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the collection, whose definition you want to get.

streets.signs.register_section()

streets.signs.register_section({
    name = "mandatory",
    description = "Mandatory",
    belongs_to = "minetest",
})
  • name is an unique technical name inside the collection for the section. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the section.
    If left blank, it will be auto-generated from the name field.
  • belongs_to is the name of the collection this section belongs to.

To avoid confusions use <collection name>:<section name> when referring to sections.

Registered sections are stored in streets.signs.registered_sections.
streets.signs.registered_sections is structured as follows:

streets.signs.registered_sections = {
    ["minetest:mandatory"] = {
        name = "mandatory",
        description = "Mandatory",
        belongs_to = "minetest",
    }
}

streets.signs.registered_sections must not be accessed directly.
Use streets.signs.get_section_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the section, whose definition you want to get.
It must have the format <collection name>:<section name>.

You can get a table of sign definitions with
streets.signs.get_section_definitions_by_collection(<collection name>).

streets.signs.register_sign()

streets.signs.register_sign({
    name = "straightonly",
    description = "Straight Only",
    belongs_to = "minetest:mandatory",
    -- all other fields used in minetest.register_node()
})
  • name is an unique technical name inside the section for the sign. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the sign.
    If left blank, it will be auto-generated from the name field.
  • belongs is the unique name of the section this sign belongs to.
    Use the form <collection name>:<section name>.

Registered signs are stored in streets.signs.registered_signs.
streets.signs.registered_signs is structured as follows:

streets.signs.registered_signs = {
    ["minetest:mandatory:straightonly"] = {
        name = "straightonly",
        description = "Straight Only",
        belongs_to = "minetest:mandatory",
        -- all other fields used in minetest.register_node()
    }
}

streets.signs.registered_signs must not be accessed directly.
Use streets.signs.get_sign_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the sign, whose definition you want to get.
It must have the format <collection name>:<section name>:<sign name>.

You can get a table of sign definitions with
streets.signs.get_sign_definitions_by_collection(<collection name>) and
streets.signs.get_sign_definitions_by_section(<collection name>:<section name>).

Updated version (2018-03-06 13:22 UTC)

Updated version (2018-03-06 13:22 UTC)

streets.signs.register_collection()

streets.signs.register_collection({
    name = "minetest",
    description = "Minetest-style Signs",
    info = "This signs are meant to be internationally understandable."
        .. "Blue signs are mandatory signs."
        .. "Yellow signs are danger signs."
        .. "White-red signs are prohibitory signs.",
})
  • name is an unique technical name for the collection. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the collection.
    If left blank, it will be auto-generated from the name field.
  • info is a human-readable info text of the collection.
    This field is optional.

Registered collections are stored in streets.signs.registered_collections.
streets.signs.registered_collections is structured as follows:

streets.signs.registered_collections = {
    ["minetest"] = {
        name = "minetest",
        description = "Minetest-style Signs",
        info = "This signs are meant to be internationally understandable."
            .. "Blue signs are mandatory signs."
            .. "Yellow signs are danger signs."
            .. "White-red signs are prohibitory signs.",
    }
}

streets.signs.registered_collections must not be accessed directly.
Use streets.signs.get_collection_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the collection, whose definition you want to get.

streets.signs.register_section()

streets.signs.register_section({
    name = "mandatory",
    description = "Mandatory",
    belongs_to = "minetest",
})
  • name is an unique technical name inside the collection for the section. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the section.
    If left blank, it will be auto-generated from the name field.
  • belongs_to is the name of the collection this section belongs to.

To avoid confusions use <collection name>:<section name> when referring to sections.

Registered sections are stored in streets.signs.registered_sections.
streets.signs.registered_sections is structured as follows:

streets.signs.registered_sections = {
    ["minetest:mandatory"] = {
        name = "mandatory",
        description = "Mandatory",
        belongs_to = "minetest",
    }
}

streets.signs.registered_sections must not be accessed directly.
Use streets.signs.get_section_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the section, whose definition you want to get.
It must have the format <collection name>:<section name>.

streets.signs.register_sign()

streets.signs.register_sign({
    name = "straightonly",
    description = "Straight Only",
    belongs_to = "minetest:mandatory",
    -- all other fields used in minetest.register_node()
})
  • name is an unique technical name inside the section for the sign. Allowed characters: [a-zA-Z0-9-]
  • description is a human-readable description of the sign.
    If left blank, it will be auto-generated from the name field.
  • belongs is the unique name of the section this sign belongs to.
    Use the form <collection name>:<section name>.

Registered signs are stored in streets.signs.registered_signs.
streets.signs.registered_signs is structured as follows:

streets.signs.registered_signs = {
    ["minetest:mandatory:straightonly"] = {
        name = "straightonly",
        description = "Straight Only",
        belongs_to = "minetest:mandatory",
        -- all other fields used in minetest.register_node()
    }
}

streets.signs.registered_signs must not be accessed directly.
Use streets.signs.get_sign_definition(name) instead,
which returns a copy of the definition or nil.
name is the unique name of the sign, whose definition you want to get.
It must have the format <collection name>:<section name>:<sign name>.

Old version

Old version

streets.signs.register_system()

streets.signs.register_system({
    id = "minetest",
    name = "Minetest-style Signs",
    description = "This signs are meant to be internationally understandable."
        .. "Blue signs are mandatory signs."
        .. "Yellow signs are danger signs."
        .. "White-red signs are prohibitory signs.",
})
  • id is an unique technical identifier for the system. Allowed characters: [a-zA-Z0-9-]
  • name is a human-readable name of the system.
  • description is a human-readable description of the system.
    Registered systems are stored in streets.signs.registered_systems.
    streets.signs.registered_systems is structured as follows:
streets.signs.registered_systems = {
    minetest = {
        id = "minetest",
        name = "Minetest-style Signs",
        description = "This signs are meant to be internationally understandable."
            .. "Blue signs are mandatory signs."
            .. "Yellow signs are danger signs."
            .. "White-red signs are prohibitory signs.",
    }
}

streets.signs.register_section()

streets.signs.register_section({
    id = "mandatory",
    name = "Mandatory",
    system = "minetest",
})
  • id is an unique technical identifier inside the system for the section. Allowed characters: [a-zA-Z0-9-]
  • name is a human-readable name of the section.
  • system is the id of the system this section belongs to.

To avoid confusions use <system id>:<section id> when referring to sections.

Registered sections are stored in streets.signs.registered_sections.
streets.signs.registered_sections is structured as follows:

streets.signs.registered_sections = {
    minetest = {
        mandatory = {
            id = "mandatory",
            name = "Mandatory",
            system = "minetest",
        }
    }
}

streets.signs.register_sign()

streets.signs.register_sign({
    id = "straightonly",
    name = "Straight Only",
    system = "minetest",
    section = "mandatory",
    -- all other fields used in minetest.register_node()
})
  • id is an unique technical identifier inside the section for the sign. Allowed characters: [a-zA-Z0-9-]
  • name is a human-readable name of the sign.
  • system is the id of the system this sign belongs to.
  • section is the id of the section this sign belongs to.

Registered signs are stored in streets.signs.registered_signs.
streets.signs.registered_signs is structured as follows:

streets.signs.registered_signs = {
    minetest = {
        mandatory = {
            straightonly = {
                id = "straightonly",
                name = "Straight Only",
                system = "minetest",
                section = "mandatory",
                -- all other fields used in minetest.register_node()
            }
        }
    }
}
@webD97
Copy link
Collaborator

webD97 commented Mar 1, 2018

Sounds good so far, but I have a few suggestions for enhancements:

  1. IDs should be autogenerated by the API. It shouldn't be the concern of a developer/content-creator to avoid name-collisions. The ID could be generated out of the description and returned from the function for later use
  2. Avoid duplicated information: If a sign has a section which has a system, the sign shouldn't need to declare the system again
  3. Encapsulate the registration tables to secure them from manipulation after they have been registered. There should be helper functions that can return a copy of an element in such a table if it is required: streets.signs.get_sign_definition(), streets.signs.get_section_definition() etc.
  4. Flatten the registration tables and index the definitions by their id. If there are helper functions, there's no need to have multi-dimensional tables. I believe this could improve the table access performance.

@Thomas--S
Copy link
Member Author

Thanks for your answser!

To 1) I think it would be good if the developer can define the id of the sign by himself. This id the developer also has to use when he refers to the sign in the code. He should be able to choose it freely. Avoiding name-collisions shouldn't be too much of a trouble either: The names must only be unique inside the section.

To 2) It is neccessary to refer to both, system and section. For example, there can be a section "mandatory" inside the "de" system and a section "mandatory" in the "us" system. If you want to shorten the definition, using <system id>:<section id> would be possible, too.

To 3 and 4) This sounds good 👍 I'll change my proposal accordingly soon.

@webD97
Copy link
Collaborator

webD97 commented Mar 1, 2018

To 1: What I wanted to achieve is a simplification of the API. In my opinion, there shouldn't be a need to specify two strings, name and ID, which are quite similar. It's just another step to understand for content creators. I don't think it's their concern to create IDs following our conventions. Autogenerated IDs would also enforce these conventions. He/she (I'll abbreviate this to 'he') will most likely not care about whatever is inside the ID. If he needs to use the ID later on, he can use the ID the function would return. Another effect of this is that we will always have the control over these IDs. If we ever need to change their semantics in a later release, it's just a change in our own code, but not in the code the content creators.

To 2: My proposal makes more sense if the IDs are autogenerated because the autogenerated ID for a section could include the system ID, e.g. in the format you mentioned.

Edit: One more thing. I'm not quite happy with the term "system". I think it's not very "speaking". Maybe something like "collection" would be better?

@Thomas--S
Copy link
Member Author

To 1) I still think we should separate ID and name in the API. Maybe I've chosen bad names, so that I have caused a misunderstanding: The ID is like the itemstring (e.g. default:dirt) in minetest and the name is like the description in the node definition. Maybe I should change the names accordingly.

I'll think about this problem in the next few days. I'll update my proposal accordingly then.

Changing the term "system" to "collection" is a good idea. I'll do this.

@Thomas--S
Copy link
Member Author

Thomas--S commented Mar 6, 2018

I've addressed most of your comments in dc07508.

It would be good, if you could review the updated proposal in the first post or in api.md (it's the same)

Here's a (possibly incomplete) list of the changes I did:

  • Renamed system to collection
  • Renamed the id field to name
  • Renamed the name field to description
  • Renamed the description field to info
  • The new description field (= old name field) is now optional. If not provided, the description will be generated out of the name field (= old id field).
  • I flattened the table as requested and introduced helper methods to access this table.
  • Update (2018-03-06 16:47 UTC): Add streets.signs.get_section_definitions_by_collection(<collection name>, streets.signs.get_sign_definitions_by_collection(<collection name>) and streets.signs.get_sign_definitions_by_section(<collection name>:<section name>)

I'm looking forward to your comments!

@Thomas--S Thomas--S removed their assignment Mar 26, 2018
@Thomas--S
Copy link
Member Author

I suggest to use the following properties for all signs:

  • 250px equals to 1m in real life
  • Indexed PNGs for smaller file size (64 colors)

@webD97
Copy link
Collaborator

webD97 commented Dec 7, 2018

Sounds reasonable

@Thomas--S
Copy link
Member Author

Thomas--S commented Dec 9, 2018

A GIMP script for generating these images can be found at https://github.com/minetest-streets/streets/blob/02690a9814b68f05e91e565884ccceffe4b8f27c/streets_api/helpers/script-fu-streets-signs.scm#L1-L162

The suggested usage is as follows:

  1. Find the image of the wanted sign.
  2. Scale it with 250px equals 1m.
  3. ln -s ~/.minetest/mods/streets/streets_api/helpers/script-fu-streets-signs.scm ~/.gimp-2.8/scripts/
  4. bash ~/.minetest/mods/streets/streets_api/helpers/streets-signs.sh <path to png> "<fixed colors>"

Example: bash ~/.minetest/mods/streets/streets_api/helpers/streets-signs.sh streets_signs_de__warning__work.png "#000000,#ffffff,#c1121c"

Please note: This script does not handle wrong user inputs! Use it with care!

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