Coding Style - Monika-After-Story/MonikaModDev GitHub Wiki
Coding Style
DO NOT CHANGE EXISTING CODE JUST TO CHANGE THE STYLE
If you are editing the existing code significantly, then it is okay to change the style. Otherwise keep any additions consistent with the nearby code. Changes that are just code style changes are a waste of resources and disrespectful to the contributor who wrote the original code, and any such changes will be undone, or rejected. This includes, but is not limited to:
- adding/removing whitespace lines
- changing comment style
- changing linebreak style
- changing indentation (except for syntax errors)
Otherwise, we don't have a strict style guideline, but here's a couple of conventions we like to follow:
Indentation
Four-space indents.
Labels
Label names should be lowercase and separated with underscores (monika_twitter
).
If you use many labels for a related subprogram, prefix them with mas
and the
name of your subprogram (i.e: mas_coolfungame_flowstart
). Exceptions to
this rule: Monika topics/greetings/farewells, although this may changed in
the future.
Certain prefixes are reserved:
greeting
- used for regular greetingsi_greeting
- used for special interactive greetingsch30
- used for key chapter 30 labelsmonika
- used for nearly every monika topicm_joke
- also used for the jokes sytemmas_poem
- used for poemgame systemmas_compliment
- used for complimentsmas_mood
- used for moodsmas_story
- used for storiesmas_apology
- used for non-generic apologiesmas_song
- used for songs (suffix with_long
for long songs)game
- used for most of the minigamesvv
- used for update-related materialv
- also used for update-related materialbye
- used for farewells
There may be more, so in general, be mindful of the labels you use.
Store
In Renpy, stores are like namespaces, except you can't have nested ones. We recommend grouping related data, constants, and functions in stores to avoid messing with the global namespace.
To create a store:
init python in mas_store_name:
var1 = 1
var2 = 2
...
# or
define mas_store_name.var1 = 1
define mas_store_name.var2 = 2
To access a store:
store.mas_store_name.var1 = 1
# or
python:
import store.mas_store_name as mas_store_name
mas_store_name.var1 = 1
We use several different stores to group different data. When deciding to make
a new store, ensure that it is not already in use. Prefix your store names
with mas_
.
persistent
is like a store, but its a special one that gets saved to disk.
Only use this if you need to save data from multiple sessions
More on this later...
Functions
If a function is very specific to a subprogram or flow, consider making it in
a store and importing it when necessary. If a function can be generalized for
many use cases, then make it in a regular init python
block (which makes it
global). Prefix global functions with mas
For documentation, either block comments (#) or doc strings (""") are fine. We don't enforce a particular way of documenting functions, but noting what the function does, its input and output vars, what it returns, and variables it assumes would be a good start:
def mas_someKindOfFunction(var1, var2, var3=None):
"""
This function does some kind of thing. Use with caution.
IN:
var1 - value of something
var3 - like the most value of something
(Default: None)
OUT:
var2 - contains modified reference to something
RETURNS:
a copy of var2
ASSUMES:
persistent.var4
"""
For function names, either camelCase or lowercase_underscores are fine.
Persistent
This store-like thing saves data to disk and is how renpy keeps track of data.
Because its already loaded with data from the stock game, avoid using this
if you can. (I.e: instead of using a persistent to check if an event has been
seen, use renpy.seen_label
or seen_event
.
Prefix all persistent variable names with _mas_
. (We are currently in
progress of converting all currently created persistent
values to be prefixed
correctly)
Constants
Define constants instead of literals when you're using them multiple times. Use UPPERCASE_UNDERSCORES for naming.
An exception to this is literals used in screens. If a screen is not
called with nopredict
, then use literals when you can, as renpy optimizes
screens with literals.
Variables
Make these descriptive please. It doesn't need to be Java-like, just enough so its somewhat easy to figure out what it is. Using abbreviations or acronyms is fine. Use lowercase_underscores for naming.
Comments
Please write comments. Even though python is readable as is, knowing the high level reason why we are doing something or the high level effects of doing something is helpful.
Line Length
Again, not really enforced, but keep them reasonable. I personally limit to 80 columns, but beyond that to probably 120 is fine. The exception is Renpy code. Renpy code cannot always be broken up into multiple lines.
Assets
Any assets you use must be in the mod_assets/
folder. If you have a ton of
assets, group them into a subfolder.
3rd-party Packages
If you can do it without using an external package, then do it without the external package. Exceptions must be discussed with the dev team. If whatever library you want to add is more than a megabyte, it almost certainly will not be allowed.