(Solved/Explained) What Specifically is "Good Practice"?

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
ArcialIntegra
Regular
Posts: 53
Joined: Mon Nov 13, 2017 12:10 am
Contact:

(Solved/Explained) What Specifically is "Good Practice"?

#1 Post by ArcialIntegra »

I feel like this should be an obvious thing that I just am not understanding, but this seems to be a variable condition established on game development. One such use of "Bad Practice" is declaring attributes in variables instead of using a Class or declaring variables before the game starts. I was wondering if there are any clear-cut rules I should know and what effect following/breaking them has on a game, its technical play-ability, and its enjoy-ability. Are these things that need to be kept in mind or are they just good ideas you should follow to make things easier in the long-run?
Last edited by ArcialIntegra on Mon Nov 13, 2017 1:51 pm, edited 1 time in total.

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3791
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: What Specifically is "Good Practice"?

#2 Post by Imperf3kt »

Mostly good practises are designed to make things easier for you in the long run. But there are a few cases where it may impact the player, such as not using () on the end of a screen name may mean that screen runs too slow on the players device. Or not defaulting variables may/will make updating your game difficult / behave unexpectedly and loading save files may have adverse effects.

At least, this is what I've seen of 'best practises'
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

ArcialIntegra
Regular
Posts: 53
Joined: Mon Nov 13, 2017 12:10 am
Contact:

Re: What Specifically is "Good Practice"?

#3 Post by ArcialIntegra »

So, it's sort of a combination of efficiency on the programmer and efficiency for the player's computer? Are there any notable examples beyond the "screen_name()" example? or is it mostly common sense stuff like "Don't include too many redundancies where not needed.", "Don't have the game try to process an excessive number of actions at once.", and "Keep your files organized."?

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: What Specifically is "Good Practice"?

#4 Post by xela »

It's a bit of all of the above.

Write your code in compliance with PEP-8, there will be more people willing to help you if you run into issues.
Keep your project well structured.
Use modern tools in favor of old (screens in favor of ui., Transform/ATL in favor of Position, ATL in favor of stuff like RotoZoom and etc.).
Don't instantly try to correct something that doesn't work with more stuff that doesn't work. So many people would put hbox in vbox in fixed in a viewport and etc. and position everything against everything until it looks right on the screen. You usually need just one container :)
Don't use functions you don't understand, every couple of month there is someone who used complex stuff like calling something in new context, ending up with a huge amount of hard to trace issues.

All of this will always amount to:
- Learn as much as you can about the Engine.
- Learn as much as you can about the Programming Languages/Scripts involved.
- Learn as much as you can about structuring your projects.
- Start off with a small project + Learn from existing examples.
Like what we're doing? Support us at:
Image

ArcialIntegra
Regular
Posts: 53
Joined: Mon Nov 13, 2017 12:10 am
Contact:

Re: What Specifically is "Good Practice"?

#5 Post by ArcialIntegra »

Okay, so it mostly amounts to common sense. I think I get it. Thanks for the help everybody. :)

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#6 Post by trooper6 »

Common Sense...but also, when I say, "current best practice is to declare your variables using default/define," I am speaking about what is going to work better using the current code base.

Earlier on, there wasn't the default keyword in Renpy, back in those days, in order to get the variables to properly save and participate in rollback...in other words, to work properly, you had to declare the variable in an init block before the start label, and then also declare it in the start label. Back then people often didn't realize that, they'd only do the init block and not in the start label, and then there'd be saving and rollback problems. Or they'd only but them in the start block and have some other sort of recognition problems. You can make it work by doing both...but that is old. PyTom created the default keyword to fix all that awkwardness. And that is the best thing to do now.

These message boards have tips and suggestions going back years. There are things suggested from years ago that will work, but they are not the modern way of doing things. And they may not be supported in the farther future. So Best Practices also involve keeping current with the language and using the most modern ways of doing things. They are usually the most efficient, the most future proof, and just better.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
xavimat
Eileen-Class Veteran
Posts: 1461
Joined: Sat Feb 25, 2012 8:45 pm
Completed: Yeshua, Jesus Life, Cops&Robbers
Projects: Fear&Love
Organization: Pilgrim Creations
Github: xavi-mat
itch: pilgrimcreations
Location: Spain
Discord: xavimat
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#7 Post by xavimat »

Some "best practices" in python are conventions. They could be different, but it's useful to know how people usually do things.

For example. Variable and functions names are written with low-case, and classes definitions with the initial in Upper-case.
So, when when we define a character in Ren'Py: define e = Character("Eileen")
Beginners do not need to know that, but more advanced users understand that "Character" is a class and not a function.

Python and Ren'Py work the same when this conventions are not followed, but it's a lot easier for other people to understand your code if they found the "usual" way of doing and naming things.
Comunidad Ren'Py en español: ¡Únete a nuestro Discord!
Rhaier Kingdom A Ren'Py Multiplayer Adventure Visual Novel.
Cops&Robbers A two-player experiment | Fear&Love Why can't we say I love you?
Honest Critique (Avatar made with Chibi Maker by ~gen8)

ArcialIntegra
Regular
Posts: 53
Joined: Mon Nov 13, 2017 12:10 am
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#8 Post by ArcialIntegra »

Okay, I think I understand. It makes it easier on you as a programmer, anybody who is proofreading your script for errors, and for RenPy to know what you're telling it to do in case the function is no longer supported in a future release. It makes sense.

trooper6, quick question about "default", do you put default in an init block or do you use it in the labels as you need it? Based on the word choice, I want to assume you toss defaults in an init block, but I want to make sure. Also, it would be this, right?

Code: Select all

init:
	default e = Character("Eileen")

User avatar
Imperf3kt
Lemma-Class Veteran
Posts: 3791
Joined: Mon Dec 14, 2015 5:05 am
itch: Imperf3kt
Location: Your monitor
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#9 Post by Imperf3kt »

You can either add default <variable> = "False/True/#" to an init block of -1 of below, or just declare any defaults before the start label (which is in an init offset of -1.)

You only set default once. After that, you use python to change it.

Again, the best practise is to put it before the start label, so it can be easily found by you / debuggers and also so variables are organised and not here, there and everywhere.
This is also why I like to add blank lines between different things. It makes it easier to find image definitions, character definitions, variables, etc. by knowing exactly where they start and end.

For example, take this excerpt from my current project:

Code: Select all

############################
##      GUI Gallery       ##
############################

############################
##        Images          ##
############################

init -1:
    image street_morning = im.Scale("background_street_morning.jpg", 1920, 1080, bilinear=True)
    image street_evening = im.Scale("background_street_evening.jpg", 1920, 1080, bilinear=True)
    
    image uncle_mugen scaled = im.Scale("gui/side_image/uncle_mugen_smile.png", 192, 108, bilinear=True)
    image uncle_mugen_01 = "gui/side_image/uncle_mugen_smile.png"
    
    image street_morning scaled = im.Scale("background_street_morning.jpg", 192, 108, bilinear=True)
    image street_evening scaled = im.Scale("background_street_evening.jpg", 192, 108, bilinear=True)
    image street_background_house_front = "street_background_house_front.jpg"
    image street_bg_dusk = "street_bg_dusk.jpg"
    
    image 001 = "commercial_building.jpg"
    image 002 = im.Scale("lonely_building.jpg", 1920, 1080, bilinear=True)
    image 003 = im.Scale("street_background_03.jpg", 1920, 1080, bilinear=True)
    image 004 = "street_bg_afternoon.jpg"
    image 005 = im.Scale("the_glorious_underpass_day.jpg", 1920, 1080, bilinear=True)
    
    
    image vp = "viewport.jpg"
    image vp_o = "viewport_outlined.jpg"
    image sc_o = "screen_outlined.jpg"
    image oelvn = Image("oelvn_dump.jpg", yalign = 0.1)
    image gf = Image("game_folder.png", yalign = 0.1)
    image ipy = "init_python.png"
        
    

############################
##       Side Images      ##
############################

    image side mugen_01 = im.FactorScale("gui/side_image/uncle_mugen_smile.png", 1.7)
    image side mugen_02 = im.FactorScale("gui/side_image/uncle_mugen_shocked.png", 1.7)
    
    image side lucy_01 = im.FactorScale("gui/side_image/lucy_smile.png", 1.7)
    image side lucy_02 = im.FactorScale("gui/side_image/lucy_happy.png", 1.7)
    image side lucy_03 = im.FactorScale("gui/side_image/lucy_surprised.png", 1.7)
    image side lucy_04 = im.FactorScale("gui/side_image/lucy_blank.png", 1.7)
    image side lucy_05 = im.FactorScale("gui/side_image/lucy_sad.png", 1.7)
    image side lucy_06 = im.FactorScale("gui/side_image/lucy_pout.png", 1.7)
    image side lucy_07 = im.FactorScale("gui/side_image/lucy_proud.png", 1.7)
    image side lucy_08 = im.FactorScale("gui/side_image/lucy_casual_smile.png", 1.7)
    image side lucy_09 = im.FactorScale("gui/side_image/lucy_casual_shocked.png", 1.7)
    image side lucy_10 = im.FactorScale("gui/side_image/lucy_casual_very_happy.png", 1.7)
    
############################
##          ATL           ##
############################
    
image viewport_example:
    xalign 0.5
    yalign 0.4
    "vp"
    pause 0.5
    "vp_o"
    pause 0.5
    repeat

image screen_example:
    xalign 0.5
    yalign 0.4
    "vp"
    pause 0.5
    "sc_o"
    pause 0.5
    repeat

image scene_swap:
    "street_background_house_front" with Dissolve(0.5)
    pause 0.05
    "001" with Dissolve(0.5)
    pause 1.5
    "002" with Dissolve(0.5)
    pause 1.5
    "003" with Dissolve(0.5)
    pause 1.5
    "004" with Dissolve(0.5)
    pause 1.5
    "005" with Dissolve(0.5)
    
    
    
############################
##         Music          ##
############################

define audio.sunshine = "music/sunshine_a.mp3"
define audio.poofy = "music/poofy_reel.mp3"

############################
##       Characters       ##
############################

define mugen = Character(None, image="mugen_01")
define mugen_shocked = Character(None, image="mugen_02")

define lucy = Character(None, image="lucy_01")
define lucy_happy = Character(None, image="lucy_02")
define lucy_surprised = Character(None, image="lucy_03")
define lucy_blank = Character(None, image="lucy_04")
define lucy_sad = Character(None, image="lucy_05")
define lucy_pout = Character(None, image="lucy_06")
define lucy_proud = Character(None, image="lucy_07")
define lucy_casual_01 = Character(None, image="lucy_08")
define lucy_casual_02 = Character(None, image="lucy_09")
define lucy_casual_03 = Character(None, image="lucy_10")

############################
##        Variables       ##
############################

default persistent.game_clear = False
#Screens line 267 sets default quick_menu to False

label start:
    $ save_name = "Nothing to see here..."
You'll notice I have separated images from scaled images, animations, side images, characters, music etc.
This makes it much easier when I need to find specific things.
Of course, this is only my personal habit and not necessary at all.
Warning: May contain trace amounts of gratuitous plot.
pro·gram·mer (noun) An organism capable of converting caffeine into code.

Current project: GGD Mentor

Twitter

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#10 Post by trooper6 »

ArcialIntegra wrote: Mon Nov 13, 2017 5:22 pm trooper6, quick question about "default", do you put default in an init block or do you use it in the labels as you need it? Based on the word choice, I want to assume you toss defaults in an init block, but I want to make sure. Also, it would be this, right?

Code: Select all

init:
	default e = Character("Eileen")
You shouldn't put default in an init block, it is redundant. default should be outside of any block. Also, use define for things that will not change after creation...like Character declarations and also image declarations.

So this:

Code: Select all

define e = Character("Eileen")
default money = 10

label start:
    e "Blah blah"
A model of this is in the code for the new updated tutorial.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

ArcialIntegra
Regular
Posts: 53
Joined: Mon Nov 13, 2017 12:10 am
Contact:

Re: (Solved/Explained) What Specifically is "Good Practice"?

#11 Post by ArcialIntegra »

trooper6 wrote: Tue Nov 14, 2017 4:43 am
ArcialIntegra wrote: Mon Nov 13, 2017 5:22 pm trooper6, quick question about "default", do you put default in an init block or do you use it in the labels as you need it? Based on the word choice, I want to assume you toss defaults in an init block, but I want to make sure. Also, it would be this, right?

Code: Select all

init:
	default e = Character("Eileen")
You shouldn't put default in an init block, it is redundant. default should be outside of any block. Also, use define for things that will not change after creation...like Character declarations and also image declarations.

So this:

Code: Select all

define e = Character("Eileen")
default money = 10

label start:
    e "Blah blah"
A model of this is in the code for the new updated tutorial.
Thanks for the info. I'll be sure to check it out! :)

Post Reply

Who is online

Users browsing this forum: Bing [Bot]