Godot: Ways Gdscript could be more user friendly and accessible

Created on 2 May 2016  Â·  41Comments  Â·  Source: godotengine/godot

Now with the effort to complete the documentation of gdscript, and with effort to even make a visual programming framework, I want to suggest a few ways to make using gdscript easier to people coming from other game engines.

Helper functions (especially for vector math):

  • Helper methods/functions for new users who are not very much into vector maths. This is something that seems to be expected when you use godot, but people coming from game maker have gotten used to the easy life. In godot to get an angle between two points - you need to write a formula. To write that formula - you need to learn vector math. When you are new to a game engine - even one with programming - GML is a much better suited to new users language. It doesnt throw vector math at you.

vectormagic-godot

In game maker language to get the distance between two points you do this:
point_distance(x1, y1, x2, y2) Returns distance between two points.

get the angle between two points:
point_direction(x1, y1, x2, y2) Returns direction from (x1, y1) to (x2,y2) in degrees.
https://en.wikibooks.org/wiki/Game_Maker_Programming/Mathematical_calculations

it's in english, easy to learn, remember, hard to get wrong. Please take a look at game maker language's helper functions. It has many good ones that let the user do the basic stuff without having to learn vector math early on. Godot throws vector math right in the start - that will drive away some people.
look at this (how to get an angle between two points- just a part of the code needed):
http://docs.godotengine.org/en/latest/tutorials/vector_math.html
var angle_in_radians = acos( a.dot(b) )
If you show that formula to a game maker developer, do you think they will get it? They have been doing this without even knowing it.

I am not saying remove the old way - just saying add helper functions to make the old way easier. It will make gdscript more accessible for everyone who is not a math wizard and just wants to make a game. These are common things. You already have similar helper functions

A trigger once condition:
I already filed this here- https://github.com/godotengine/godot/issues/4514
Basically adding 'and trigger_once' to an if case, would force it to trigger whats inside it only once, even if the condition is true for more than one frame. That way we dont have to create new arbitary variables to switch it on and off, keep track of them and invite more room for errors.
example:

if myvalue>500 and trigger_once:
doSomething()

Replace variable name globally:
A way to change a variable name everywhere on a script. Does godot's editor have a way to do that? I notice that in recent builds when I highlight a variable, it gets highlighted on copies. But can I also rename the variable everywhere by renaming it at one place?

Be able to expose a node and all of it's variables to the debugger
-so we can see them change while the game is running - without having to print them out with bazillion commands.

Autocomplete code from other scenes

  • when you spawn an instance from an external scene - code autocompletion for it does not work. It would be nice if it did.

I believe if you add a little bit of user friendliness to gdscript - especially to aid common tasks such as the ones I list here - it will make it much less scary to newcomers.

can you think of other ways gdscript could be made easier to use?

archived discussion gdscript

Most helpful comment

if you want to make games, there is no such thing about being a new user.
Learn vector math. There is even a nice tutorial in the Godot docs.

Regarding autocomplete from other scenes, autocomplete will always work as
long as type can be infered, if it can't it won't work. We'll add optional
typing eventually so you can autocomplete better.

On Sun, May 1, 2016 at 7:00 PM, Todor Imreorov [email protected]
wrote:

Now with the effort to complete the documentation of gdscript, and with
effort to even make a visual programming framework, I want to suggest a few
ways to make using gdscript easier to people coming from other game engines.

_Helper functions (especially for vector math):_

  • Helper methods/functions for new users who are not very much into
    vector maths. This is something that seems to be expected when you use
    godot, but people coming from game maker/glm have gotten used to the easy
    life. In godot to get an angle between two points - you need to write a
    formula. To write that formula - you need to learn vector math. When you
    are new to a game engine - even one with programming - GML is a much better
    suited to new users language. It doesnt throw vector math at you.

[image: vectormagic-godot]
https://cloud.githubusercontent.com/assets/6495061/14944597/bf25fa66-0fef-11e6-8dd8-0ff2b8df7cc4.PNG

To get the distance between two points you do this:
point_distance(x1, y1, x2, y2) Returns distance between two points.

get the angle between two points:
point_direction(x1, y1, x2, y2) Returns direction from (x1, y1) to (x2,y2)
in degrees.

https://en.wikibooks.org/wiki/Game_Maker_Programming/Mathematical_calculations

it's in english, easy to learn, remember, hard to get wrong. Please take a
look at game maker language's helper functions. It has many good ones that
let the user do the basic stuff without having to learn vector math early
on. Godot throws vector math right in the start - that will drive away some
people.
look at this (how to get an angle between two points- just a part of the
code needed):
http://docs.godotengine.org/en/latest/tutorials/vector_math.html
var angle_in_radians = acos( a.dot(b) )
If you show that formula to a game maker developer, do you think they will
get it? They have been doing this without even knowing it.

I am not saying remove the old way - just saying add helper functions to
make the old way easier. It will make gdscript more accessible for everyone
who is not a math wizard and just wants to make a game. These are common
things. You already have similar helper functions

_A trigger once condition:_
I already filed this here- #4514
https://github.com/godotengine/godot/issues/4514
Basically adding 'and trigger_once' to an if case, would force it to
trigger whats inside it only once, even if the condition is true for more
than one frame. That way we dont have to create new arbitary variables to
switch it on and off, keep track of them and invite more room for errors.
example:

if myvalue>500 and trigger_once:
doSomething()

_Replace variable name globally:_
A way to change a variable name everywhere on a script. Does godot's
editor have a way to do that? I notice that in recent builds when I
highlight a variable, it gets highlighted on copies. But can I also rename
the variable everywhere by renaming it at one place?

_Be able to expose a node and all of it's variables to the debugger_
-so we can see them change while the game is running - without having to
print them out with bazillion commands.

_Autocomplete code from other scenes_

  • when you spawn an instance from an external scene - code
    autocompletion for it does not work. It would be nice if it did.

I believe if you add a little bit of user friendliness to gdscript -
especially to aid common tasks such as the ones I list here - it will make
it much less scary to newcomers.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/godotengine/godot/issues/4516

All 41 comments

if you want to make games, there is no such thing about being a new user.
Learn vector math. There is even a nice tutorial in the Godot docs.

Regarding autocomplete from other scenes, autocomplete will always work as
long as type can be infered, if it can't it won't work. We'll add optional
typing eventually so you can autocomplete better.

On Sun, May 1, 2016 at 7:00 PM, Todor Imreorov [email protected]
wrote:

Now with the effort to complete the documentation of gdscript, and with
effort to even make a visual programming framework, I want to suggest a few
ways to make using gdscript easier to people coming from other game engines.

_Helper functions (especially for vector math):_

  • Helper methods/functions for new users who are not very much into
    vector maths. This is something that seems to be expected when you use
    godot, but people coming from game maker/glm have gotten used to the easy
    life. In godot to get an angle between two points - you need to write a
    formula. To write that formula - you need to learn vector math. When you
    are new to a game engine - even one with programming - GML is a much better
    suited to new users language. It doesnt throw vector math at you.

[image: vectormagic-godot]
https://cloud.githubusercontent.com/assets/6495061/14944597/bf25fa66-0fef-11e6-8dd8-0ff2b8df7cc4.PNG

To get the distance between two points you do this:
point_distance(x1, y1, x2, y2) Returns distance between two points.

get the angle between two points:
point_direction(x1, y1, x2, y2) Returns direction from (x1, y1) to (x2,y2)
in degrees.

https://en.wikibooks.org/wiki/Game_Maker_Programming/Mathematical_calculations

it's in english, easy to learn, remember, hard to get wrong. Please take a
look at game maker language's helper functions. It has many good ones that
let the user do the basic stuff without having to learn vector math early
on. Godot throws vector math right in the start - that will drive away some
people.
look at this (how to get an angle between two points- just a part of the
code needed):
http://docs.godotengine.org/en/latest/tutorials/vector_math.html
var angle_in_radians = acos( a.dot(b) )
If you show that formula to a game maker developer, do you think they will
get it? They have been doing this without even knowing it.

I am not saying remove the old way - just saying add helper functions to
make the old way easier. It will make gdscript more accessible for everyone
who is not a math wizard and just wants to make a game. These are common
things. You already have similar helper functions

_A trigger once condition:_
I already filed this here- #4514
https://github.com/godotengine/godot/issues/4514
Basically adding 'and trigger_once' to an if case, would force it to
trigger whats inside it only once, even if the condition is true for more
than one frame. That way we dont have to create new arbitary variables to
switch it on and off, keep track of them and invite more room for errors.
example:

if myvalue>500 and trigger_once:
doSomething()

_Replace variable name globally:_
A way to change a variable name everywhere on a script. Does godot's
editor have a way to do that? I notice that in recent builds when I
highlight a variable, it gets highlighted on copies. But can I also rename
the variable everywhere by renaming it at one place?

_Be able to expose a node and all of it's variables to the debugger_
-so we can see them change while the game is running - without having to
print them out with bazillion commands.

_Autocomplete code from other scenes_

  • when you spawn an instance from an external scene - code
    autocompletion for it does not work. It would be nice if it did.

I believe if you add a little bit of user friendliness to gdscript -
especially to aid common tasks such as the ones I list here - it will make
it much less scary to newcomers.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/godotengine/godot/issues/4516

yes but what if you are some impatient kid that is just getting into godot. They want to try and make something cool quickly, but the learning curve is steep. To be able to do some basic enemy AI - to get it to walk towards the player - suddenly vector math.
In game maker they could just write that expression. They also have the option to do it the advanced way (godot's), but they dont have to at this point and are getting the reward of seeing their thing work as expected. That makes the more invested in the engine - as it allowed them to do the cool stuff early on. For the more advanced cool stuff they still need to learn vector math of course.

I quoted heartbeast, because he is a famous game maker teacher. He has written books, made classes for udemy and other sites. He has experience making games and teaching others to make them in game maker. And he is now switching to doing godot stuff as well. His first point was right away the vector math. We might be able to get some good feedback from that guy. :)

Anyone could make some library that is an add-on for impatient kids so they
have all the functions they need, game maker style. It doesn't have to be
built-in integrated..

On Sun, May 1, 2016 at 7:15 PM, Todor Imreorov [email protected]
wrote:

yes but what if you are some impatient kid that is just getting into
godot. They want to try and make something cool quickly, but the learning
curve is steep. To be able to do some basic enemy AI - to get it to walk
towards the player - suddenly vector math.
In game maker they could just write that expression. They also have to
option to do it the advanced way (godot's), but they dont have to at this
point and are getting the reward of seeing their thing work as expected.

I quotes heartbeast, because he is a famous game maker teacher. He has
written books, made classes for udemy and other sites. He has experience
making games and teaching others to make them in game maker. And he is now
switching to doing godot stuff as well. His first point was right away the
vector math. We might be able to get some good feedback from that guy. :)

—
You are receiving this because you commented.
Reply to this email directly or view it on GitHub
https://github.com/godotengine/godot/issues/4516#issuecomment-216076476

yes of course, and the new plugin system will allow that.
But how about some of the other stuff - it wont be easy with a plugin.

we make it so it's easy with a plugin

On Sun, May 1, 2016 at 7:19 PM, Todor Imreorov [email protected]
wrote:

yes of course, and the new plugin system will allow that.

But how about some of the other stuff - it wont be easy with a plugin.

—
You are receiving this because you commented.
Reply to this email directly or view it on GitHub
https://github.com/godotengine/godot/issues/4516#issuecomment-216076645

Is this not the same?
point_distance(x1, y1, x2, y2)
Vector2(x1,y2).distance_to( x2, y2 )

Vector also has some angle functions

If we're going to add more utility functions to help with math, one might want to take inspiration from the Blender mathutils module.
https://www.blender.org/api/blender_python_api_2_77_0/mathutils.html

I'm not arguing for a 1-to-1 copy of the module in Godot, but perhaps the more useful functions (that we have no equivalent of) can have a GDscript equivalent?

I will also note that it may not make things as trivial as with GameMaker, but it will take care of some of the more complex math.

Somewhat related, but I've actually just recently released a module on my own page covering some math functions people might find useful. It contains some functions reimplemented from Unity moreso than Game Maker, but it may still prove useful for some people and I will be continuing to add to it as needed. These were originally implemented in GDScript, but it seemed sensibile to port them to C++ for the sake of performance.

https://github.com/SaracenOne/godot_math_extension

Yes, I wonder if the helpers asked by blurymind would be faster in the source-code rather than coded in GDScript by the user. The more things you choose to code in C++ the more the engine is faster ? Or is it purely theoritical ?

On the vector math helpers, @AlexHolly is right - now I see that we do have helper functions for distance. There are some angle ones too. They are equivalent to the ones in game maker. The godot tutorials dont really talk about them and instead throw us in vector math formulas - so they are easy to overlook.

Perhaps the documentation here (http://docs.godotengine.org/en/latest/tutorials/vector_math.html) should be updated to mention them all. Distance_to is mentioned, but none of the other very very useful ones like angle_to are.

Perhaps we can look at other GML script helper functions that make it a better option for beginners?
I forwarded this thread to heartbeast, who is a GML expert. See if we can find some other helper functions that clearly make GML a better choice for beginner programmers. I think studying the competition is a healthy thing for an engine. We can learn from their success a thing or two.

Let's put our heads together and come up with a list of helper functions that will make life easier. Which ones of the ones @Ace-Dragon mentioned and @SaracenOne has would be really worth having added?

On the trigger once function - we need to come up with good syntax for it. If anyone has ideas, please visit #4514 if you can come up with something. So far I thought of this:

if time>500:
 trigger_once: stuffHappens()

Maybe just add something like this in global scope?

It's a bit annoying when you have multiple args but it's easy to implement

func _ready():
    set_process( true )

var counter = 0

func _process(delta):
    print("loop " + str(counter) )
    trigger_once( 1==1, "do1" )
    trigger_once( counter>5, "do2" )
    if( counter>7 ):
        set_process( false )

    counter+=1


func do1():
    print("do1")

func do2():
    print("do2, reset do1")
    trigger_reset("do1")

var dict = {}
func trigger_reset(funct):
    dict.erase( funct )

func trigger_once(condition, funct):
   if( !dict.has(funct) ):
      if(condition):
         call( funct )
         dict[ funct ] = ""

Can't you already accomplish this with coroutines? Also a timer module could just be added if you want it to be friendly.

The vector stuff is already there, at least for vector2s. To change a variable name just use Replace (ctrl-R).

@vnen made an awesome trigger once via a singleton:
https://github.com/godotengine/godot/issues/4514#issuecomment-216682808
it helps programmers avoid recursive triggers.

It works really great, but I really wish someone makes a built in version for gdscript parser too.
He's open to someone else doing a PR, but in the end it really depends on @reduz

I'm not willing to mess with the GDScript parser, at least not without @reduz approval. Though if someone wants to tackle this and make a PR, I'm not against it.

Some things could be made even better:

  • Not having to manually create the trigger at the start of the scene - for each time you use a trigger - the trigger could create itself during runtime.
  • if its built in, you wouldnt have to set it up ever time you start a project

If it's not gonna make it to gdscript, perhaps it would be awesome to come up with a plugin version of it. Does the plugin system in godot support adding singletons too?

On the issue of using radiants and degrees.
Here is an example - in godot's editor - the node2d node:

In the editor when you set the 'rot' value to 90, you get this.
screenshot from 2016-05-06 12-50-16

However when you do that in code, you get this:
wrongsetrot

the reason for that is set_rot uses radiants instead of degrees - while the editor uses degrees, but initially the user would expect that setting a value in the editor and in code should be consistent, and they get an unpredictable result.
So the user has to convert the value like this set_rot(deg2rad(90))
The worst part about this case scenario is that the code will parse successfully, without any error message, but will result in an unexpected outcome.

This leads me to two points:

  1. The editor and gdscript are not consistent with the value type they take for rotations
  2. In order to know the type of variable that is expected, you need to search the class api documentation explicitly.
    In game maker, the autocompletion gives hints like this:
    autocomplete_image
    Immediately you know what type of value is expected there!
    To make this even more awesome than godot, gamemaker users can write hints in their own functions. Defining a hint is as simple as:
    intelligent-code-completion

http://gamemakerblog.com/2014/01/02/how-to-add-intelligent-code-completion-to-scripts/

I filed this to another Issue ticket - so as to discuss it individually:
https://github.com/godotengine/godot/issues/4569

@blurymind in #4511 @reduz confirmed that the degrees in editor and radians in script is intended:

This behavior is intended, Godot works with radians internally, but will
show degrees when presented to the user via the UI.

@mattiascibien that is ok, but it wouldnt confuse new users if godot had hints in autocompletion like other game engines/code editors. :)
This is a point to make about user friendliness of gdscript.

Imagine how much easier/faster it will become for people to learn/transition to gdscript if we had this!

@blurymind
What is this then?

Also you can use set("transform/rot",90) if you really need to use degrees instead of radians. With set/get function you can access all the properties visible in the editor.

@Kermer how did you make that hint appear? When I type and it autocompletes nothing ever appears.

@reduz the hints are too hidden. They dont appear as you type, dont appear when you hover over them. How do they appear?

'float rot' also is not telling us that is expects the value to be in radiants. It's only telling us that it is a float - which is I guess better than nothing.

@blurymind They should show up automatically, when you autocomplete it using enter. I had the same issue here https://github.com/godotengine/godot/issues/2378 At the end, I closed it, but I still don't like the Godots hint system.

I agree with you @GlaDOSik , because of how it is currently designed, the feature is almost invinsible to the user. I rarely hit enter - rather I continue by typing the values. Not seeing the hint as I type, I get to the conclusion that hints dont work sometimes if ever.

Now that I know, I will hit enter more often, but still hope to see at least more information show in the hint. set_rot using radiants for example, could show that it expects a radiant float

On the topic of degrees vs. radians, I would expect the editor to use degrees (because it's easier to think and type) and the code to use radians (because it's easier to do math). This thing about what "user expects" can become very subjective.

I agree that it should be better hinted. I don't agree the behavior should be changed.

I also always saw auto-completion and method signature hints, if it's not showing for you it might be a bug.


Some points in the OP are real issues, the others are arguable.

Namely, the real issues are:

  1. Replace variable name globally: what we do need are refactoring tools, but that's hard with dynamically typed language, so it wouldn't be completely automatic.
  2. Be able to expose a node and all of it's variables to the debugger: we do need a way to see contents of arrays and dictionaries and also the properties of nodes. The debugger can be greatly improved in this regard. There's #4103 opened about it.
  3. Autocomplete code from other scenes: and also from other scripts. Again, hard to do with dynamically typed language, but to some extent it should be possible (since the auto-completion works for the same scene and script). There are #1039 and #3168 about this.

@vnen i agree with you on all accounts. I dont think the behavior should be changed, just didnt know that you have to hit enter to see the hint. It would be nice if the hint mentioned radiants.

On the debugger - it would be nice if we could add specific variables to follow or entire nodes. It might be an overkill if it shows everything and will probably slow down the game more.

@blurymind I guess it's a matter of coding habits. When I code in Java, I bash Ctrl+Space and Enter all the time (even for simple for loops). I would like to see argument data types in the main autocompletion window and hint system could show documentation. Yeah, I'm very spoiled by NetBeans IDE and Javadoc.

@GlaDOSik its perhaps those habits that get us used to a certain way of getting information and thats why transitioning to godot - some of it's features (such as this one) are hidden to us initially.

At my issue post I suggested to at least show the hint of the actively selected autocomplete item as you type the text, rather than only after you hit enter. But i guess now that i know about this, it doesnt really bother me that much. The hint information on type of values could be better of course. If a degree or a radiant is expected could be noted.

I just noticed that Array type variables can not be resetted, like other types of variables in godot:
arrayss

Whats worse is that if you make an array in gdscript like this:

export var myArray = [1,2,8,4]
for test in myArray:print('whyy',test)

and forget to give it any values in the inspector, the array will simply be empty. The for loop will not print at all!

In essence array type variables have no default value that they can be resetted to. They do not work at all if you have not assigned anything to them in the inspector, while they have the export tagged in gdscript.

This is inconsistent with strings, ints, floats and what have you. :)
Filed this here as well: https://github.com/godotengine/godot/issues/4586

for anyone who likes to discuss it.

this went from user friendly gd script to talking about UI heh

The array note affects gdscript. Basically if you add 'export' to an array that you create, its initial values in gdscript will not work - unless you go and set them again in the editor

report that in a separate issue, though I'm now sure if this can be fixed,
arrays are shared

On Sat, May 28, 2016 at 5:41 AM, Todor Imreorov [email protected]
wrote:

The array note affects gdscript. Basically if you add 'export' to an array
that you create, its initial values in gdscript will not work - unless you
go and set them again in the editor

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/4516#issuecomment-222297558,
or mute the thread
https://github.com/notifications/unsubscribe/AF-Z25HCGZQqgaI4ECoCtusDzW__c2AWks5qF_-ygaJpZM4IVB4u
.

Already did :)
On 28 May 2016 11:56, "Juan Linietsky" [email protected] wrote:

report that in a separate issue, though I'm now sure if this can be fixed,
arrays are shared

On Sat, May 28, 2016 at 5:41 AM, Todor Imreorov [email protected]
wrote:

The array note affects gdscript. Basically if you add 'export' to an
array
that you create, its initial values in gdscript will not work - unless
you
go and set them again in the editor

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/godotengine/godot/issues/4516#issuecomment-222297558
,
or mute the thread
<
https://github.com/notifications/unsubscribe/AF-Z25HCGZQqgaI4ECoCtusDzW__c2AWks5qF_-ygaJpZM4IVB4u

.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/4516#issuecomment-222302619,
or mute the thread
https://github.com/notifications/unsubscribe/AGMbVUtX4-7T3_HqSNB514NFaqUSBleQks5qGB9ZgaJpZM4IVB4u
.

Another thing that would make godot nicer and encourage users to read the api documentation - a right click 'search doc' command that lets you search for what a method does by selecting it, right clicking>'search doc'

There was a context search, but it seems it was removed at some point (?).

There was a context search, but it seems it was removed at some point (?).

I don't know what you mean. You can always press Shift+F1 to open the contextual help search. That has not changed.

Strange, could have sworn it didn't work anymore after the help system changed. Even asked on IRC a couple times to be sure. Trying it now, it works inside the editor. Go figure.

Anyway, my bad, then.

Sorry, my bad as well :)

On Sat, Jul 23, 2016 at 4:07 PM, Hetdegon [email protected] wrote:

Strange, could have sworn it didn't work anymore after the help system
changed. Even asked on IRC a couple times to be sure. Trying it now, it
works inside the editor. Go figure.

Anyway, my bad, then.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/4516#issuecomment-234723010,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGMbVRlRrkTWbSdkW7f8I1o3TWMCANcDks5qYi5CgaJpZM4IVB4u
.

I use Vim a lot to write source codes (I find its capabilities unrivalled, also because it allows me to keep the hands on the keyboard all the time). I cannot use autocompletion capabilities of Vim in the best way, since I don't have the dictionaries. Is there a way to retrieve them from Godot?

@Aster89 If you can write your own auto-complete provider plugin for vim, use this: https://github.com/neikeq/gd-autocomplete-service

@neikeq, Could you please help me (or give me some reference on how) to understand your plugin? I read a bit the README file: the "Getting the project path" section is clear to, the same (more or less) for the "Response example" part, but I didn't understand very well what/where shoud I do and what is done by your plugin. (I'm new to OOP, Godot being my first approach to this world!)

Here is something that is somewhat related to making gdscript more user friendly:
https://github.com/godotengine/godot/issues/11866
godot needs to convert any vector2/3 variables to strings with var2str before writing them to json file and vice versa.
This can very often lead to tons of convoluted for loops just to clean up an array structure from vector2/3's with str2var - which would otherwise be written wrongly to the json file.
By wrongly I mean that when reading them, godot wont be able to parse them as vector2/3

My request is to have the json parser (optionally if you wish) - do that automatically- even if said variables are inside mixed arrays

@akien-mga Close this, maybe? No concrete discussion anymore at this point & quite old. If anything new comes up, creating a new issue would probably be better at this point.

Agreed, this issue is too long and partly obsolete. If some points mentioned here are still relevant, please open issues for each of them so that they can be discussed and implemented separately.

Was this page helpful?
0 / 5 - 0 ratings