-
Notifications
You must be signed in to change notification settings - Fork 0
How to Contribute
- Indentation
- New Lines (Vertical Spacing)
- Spaces (Horizontal Spacing)
- Braces
- Parentheses
- Logical Operators
- Pointers
- Function Prototypes
- Commenting
- To begin contributing, download the github desktop app here
- Clone the desired project: File>Clone Repositiory>Enter the URL of the repository page
- Create a branch as your name
- Hit publish branch
- Hit open this repository in explorer in the middle of the app
- Open the project in your favorite text editor
- Make your edits and save the file
- On the GitHub desktop app, commit the changes in the bottom left, adding a title and description of your changes
- Click Push Origin at the top right
- Go to GitHub online and create a pull request under the Pull requests tab.
- Wait for your request to be reviewed
This project is coded in GML. When programming, it is important you follow these standards to increase readability and avoid errors.
There are many types of variables and separating which type is which will greatly increase readability. In general variable names should be short and concise. However, if a slightly longer name will increase readability, typing long variable names will not be the death of us. Follow these guidelines:
The typical variable you define, such as player_health or room_width should be written in all snake_case, with words separated by capitalizing the first letter of the next word. Numeric suffixes can be added directly to the end such as block3. Note: variable names can never start with number. Not 2player but player2.
Constants are definitions that do not change, ever. For example pi or player_speed (If the player always travels at the same speed). Think, "Am I ever going to change this variable? Ever?" If the answer is no, it's a constant. Constants are written in all caps, e.g. PI or PLAYER_SPEED.
Counters are variables that get incremented or decremented in a for or while loop. If the variable is being used specifically for counting in that loop, i j and k should be used. For example:
int i;
int j;
for (i=0; i<10; i+=1){
for (j=0; j<10; j+=1){
// Code
}
}
All functions will be declared after main, with a function prototype copied to a designated // Function prototypes section before main. See Function Prototypes on how to style the prototype statement.
The defacto standard console width is 80 characters, so no single line output should be more than this.
Newline characters \n should be implemented at the end of a print statement because of line-buffering which may cause a line to not appear until a newline character. Source
The style guide is standard and following it will make your code easier to read, especially for reviewers. The guide may seem nitpicky but getting into the habit of good coding will make things easier for you and others.
Indentation is not required in C but is highly recommended. Every level or loop of code that is nested should be indented one further than the level right above it. Here's an example:
switch (state){
case 0:
// Do first thing
case 1:
// Do second thing
}
Note how each block of nested code is indented one more level than the last. It's easy to see where all the cases are for the switch statement because they're all at the same indentation or column.
Also note the usage of new lines in the above example, one after each block of code. In general, add a newline after each loop or statement that doesn't contain the "final level" of code or the code that actually does something: action code, if you will. The exception is that there is no new line needed when the next line is indented further than the previous line. That is, a new line of code should not be both indented and have a blank line. There is no line after the switch statement because the case statement is already indented. There is no line after the case 0: or case 1: because they contain the action code. However! There is a line between the case statements because they are not action code. Here's another example:
// Other code, unrelated to the for loop
int i;
for (i=0; i<10; i+=1){
// Do something each time
if i < 5{
// Do something else when i<5
}
}
Basically code is broken into blocks by newlines. The declaration int i; is related to for loop so there is no blank line after it. The "Other code" however is unrelated and therefore there is a blank space after it. The action code is directly under the for loop and if statement. The if statement is not, itself, action code though, so it has a line separating it from the action code above it since it is on the same indentation as it. Don't be stingy with space! Each statement deserves it's own line. Don't use x = 1; y= 1;, instead do:
x = 1;
y = 1;
C also allows for control statements to all be on one line if there is only one line of code to execute. For readability, it is preferred this is avoided unless a long list of control statements all execute one line of code each.
// Bad
if lives < 1 destroy_instance();
// Good
if lives < 1{
destroy_instance();
}
// Also good
if condition_1 action_1;
if condition_2 action_2;
if condition_3 action_3;
if condition_4 action_4;
There's endless amounts of space and since C is not a whitespace language, it just ignores all the unnecessary lines anyway. It's just for readability!
Space can convey meaning and make what is happening in the code much clearer if we use it consistently. I'll try to list as many examples as I can to show you when a space is appropriate and when it is not.
| Situation | Needs spaces? | Example(s) |
|---|---|---|
| Variable Assignment | Yes | speed = 5 |
| Operators | Yes |
speed += 5 height * room_height speed < 5
|
| Parameter Assignment | No | function(param=1) |
| After keyword1 | Yes |
while (x > 2 && y < 3){ |
for loop assignments |
No |
for i=10 etc. |
for loop sections |
Yes |
for (i=10; i>0; i++) (After semicolons) |
| After commas | Yes | fuction(param1, param2, param3) |
| Around parentheses | No | grid = (room_height / 64) * 5 |
| After statements, before braces | No | if x == true{ |
1This differentiates them from function calls where there is no space. Source
Include immediately after the statement, regardless of its size. End them on a different line, aligned with the beginning of the statement they refer to. Most text editors take care of this automatically.
if statement{
if statement{
// Do stuff
}
}
Don't add an extra line between braces, just keep the all on different lines.
Use parentheses when necessary or when they improve readability, try not to overuse them. C follows order of operations so 2 + 2 * 2 = 6 not 8, no parentheses required.
In regard to control statements, they are not required! However, do use them if the statement is lengthy or has multiple conditions.
Good:
if speed < 5{
speed += 1;
}
Also good:
if (speed < 5 and energy > 5) or health < 10{
speed += 1;
}
Parentheses may be needed with these if you're applying them to multiple terms.
if lives > 0 && health <= 0{
// Restart
}
No parenthesis needed
or:
if !(speed == 5){
speed = 5
}
Note: The parentheses here are needed or the ! will only negate the speed and not the comparison speed == 5. No parenthesis are needed for negating boolean values, e.g. if ! is_alive{ would work if is_alive is a boolean (true or false).
Pointer declarations will have the indirection operator attached to the variable name, not type. For example int *some_ptr; not int* some_ptr;. This more closely corresponds to C's language grammar and avoids confusion in the case of int *some_ptr, i;, where i is just an int.
Per the naming conventions all pointers must end with _ptr.
Function prototypes will be declared before main and will include the parameter names from the function. This will allow for a simple copy and paste of the function declaration statement to the top when it is done.
// Function prototypes
void display_results(struct Player *player_ptr);
Comments are critical for code that will be reviewed, shared, and edited. As is our quest in coding, knowing when and how much to comment will improve readability and manageability. There are a few different types of comments.
These comments take place at the beginning of a function. The Documentation should include the function's purpose, parameters, and what it returns. For documentation a multiline comment is used with the beginning and ending line taking up all 80 characters of a standard console display.
/******************************************************************************
* Function: display_results
* Description: Print list of results
* Parameters: playerPtr, Player *, pointer to the player
* Return: void
******************************************************************************/
void display_results(struct Player *player_ptr){
// Actual Code
Finally in-line comments can help supplement code. In general, if the style guide and standards are followed, code should be fairly readable on its own. However, if further explanation is needed besides what is obvious, in-line comments are required.
In-line comments use the // at the beginning of the line and should always take place before the code they are referring to on a separate line, (except in the case of a long list in which each line needs a comment, then they can go on the same line).
All comments should start with one space as per suggested in Python's style guide PEP 8, and discussed on this forum. This will allow for easy identification of comments vs commented-out code.
// Comment about code
// Code itself
In-line comments should say why a certain thing is being done instead of simply restating what is happening in the code. For example:
// Check to see if the speed is less than 5, then set it to 5
if speed < 5{
speed = 5
}
This is bad. The comment states the obvious. So what do you comment here? Nothing. Comments are for explaining the ambiguous, if they don't make something clear that wasn't clear before they shouldn't be included. Here's a good comment to reduce ambiguity:
// If the player is below the kill line, kill him
if obj_player.y < ((room_height / 64) + 8) * level{
instance_destroy(obj_player)
}
The random coordinates may not be obvious to someone looking at this code for the first time. The comment explains why the coordinate is used. Of course, even better might be to use a variable: kill_line = (room_height / 64 + 8) * level since the line if obj_player.y < kill_line would be self explanatory. Anyway, use in-line comments sparingly, always asking yourself if you could still explain this code in a month, or year. If not, add a comment.
A short inline comment should be included before a section of code (more than 1 or 2 lines) to identify the purpose of the code, even if the code is self-explanatory. This is to allow programmers to quicky break down what's going on in an event without reading all the code.
// Release object
with instance_destroy(other){
inventory -= 1;
sprite_index -= 1;
}
You see a problem with the game. Or maybe something you think should be added? Time to create an issue.
This is done in the issues tab by hitting new issue. Several templates will appear to help you construct a well formatted issue. If you have a bug, fill out the bug template. If you don't have a specific idea but want to discuss something or brainstorm ideas, fill out the discussion thread template (don't forget to label this issue as discussion).
After you fill out the issue form, label it with the correct issues, add it to related projects, milestones, etc. Well categorized issues are important if someone is trying to find issues related to a specific problem.
We use Markdown for all our issue formatting. For a very succinct lesson in Markdown formatting visit this site.
Generally leave closing an issue to the person who opened it or the code reviewer who pulled the solution to the issue. If an issue has had no attention and seems it will not be dealt with, submit a comment mentioning the issue creator (@USERNAME using their username) asking if it can be closed.
If an issue is tagged bug and you follow the reproduce steps but can't reproduce the bugs do not close it. Instead label it with could not reproduce and wait for another user to confirm it.
If you're searching for an issue and can't find it, don't forget to search the closed issues as well.
See the labels page for a list of labels.
A pull request is how code is added from your branch to the main (or master branch). You request that the code be reviewed, and once it is approved, you can merge it into the master's branch. It is important you read and follow the steps listed below as they help protect the master branch from bugs and glitches, as well as give order to the whole process.
So how do you submit a pull request? Well, once you have completed an issue:
- Carefully test your code. It should compile without errors, perform the intended action, and not alter unrelated sections of the game
- Commit the changes to a branch named after you (if you don't have one go to
Branch>New Branchon the GitHub Desktop) - Submit a pull request on the pull request tab
- Type in relevant information including issue number into the prompt
- Go to your issue and label it with the green
pull request submittedlabel so others know you have completed that issue and are just waiting on a review - Don't close the issue. The reviewer will close it when he/she has ensured your code can be safely added to the
masterbranch. In the meantime others will want to know that your code has not yet been added
Your pull request will be reviewed and the reviewer will almost always find something that needs to be changed, whether it be a small bug or something larger. Once you receive change requests and make the changes, they will be automatically added to your pull request as you commit them to your branch.
Be sure to update the Changes Requested category if a change alters the content of your pull request. If you feel a reviewer has requested a change that is unnecessary or incorrect, politely point this out in a comment on the pull request. If the the reviewer still denies your change and you still believe it to be a good one, you can request an additional review. If your reviewer(s) do not approve of the change, don’t lose heart! Not every change suggested will get into the main game. Move on to another change.
Note: If you do have to remove part of a pull request, don't delete it! You can just make the change on your branch and make another commit to override the previous one.
Reviewing submitted pull requests is a necessary step to building a successful project. It's not always fun, but its necessary. If you want to review code, there are some requirements you should meet:
- You should be familiar with C in general
- You should be aware of what makes code efficient or inefficient so you can make suggestions for submitted code
- You should be familiar with the project in general to prevent subtle bugs from occuring in other project sections due to code that has unintended consequences, such as an effect on networking.
Reviews can take 3 forms:
- Approve - Submit the review without requiring changes to the code
- Request Changes - Submit the review requiring changes to the code
- Comment - Make a suggestion without approving or rejecting the code
The comment is just a note for the reviewee, and may be submitted by anyone as it does not give or reject approval.
Reviews should be clear and concise to save time for both the reviewer and the reviewee. When writing a review you can type suggestions directly attached to lines of code by going to the files changed and clicking on the blue comment below the line. You can also suggest a correction here using ctrl-g that the reviewee can use to automatically change the code without submitting another commit. In-line comments should be used when possible for smaller errors, one-time mistakes, and typos. If a larger issue is present such as:
- Code that raises numerous errors
- Code that effects unrelated portions of the project
- Code that is generally inefficient
A general comment can be submitted at the end of the review. Reviews should always be kind and respectful. Suggest rather than demand changes and be open to different ways of doing things, even if they aren't how you pictured the solution to an issue.
Reviews must be thorough, even if just to educate the reviewee. Every pull request is a learning experience. Here's what to point out to reviewees (based on guidelines written by ryanmcdermott here)
- Styling issues - improper indentation, new lines, spaces, variable capitalization, etc. Just mention it and/or propose the proper style, don't dwell on it. If someone consistently has improper style, politely direct them to the Style Guide in the general review
- Ambiguous function names - If a function name is very confusing, mention it, suggest a better one if you can.
-
Long functions - If a function is very lengthy, make sure the function is only completing it's specified task. For example if the function is
scr_deal_damage, make sure the function only deals damage, and doesn't also check if the player is dead. That should use a different function, even if thescr_check_if_deadfunction is called duringscr_deal_damage - Lacking comments - If code is complex and you have to spend a lot of time interpreting it, it should be commented. Fuctions should all have proper documentation. If a strange approach is taken, a comment should explain that approach to avoid confusion later. Follow the style guide. Don't worry too much about unneeded comments unless they are excessive.
- Side effects - If code is going to cause obvious complications or is needlessly limiting, a suggestion should be made for more flexible code
- Error catching - Code should catch exceptions to prevent fatal errors. What if the modified object is destroyed? What if a different room is entered?
-
User input - Along the same lines, errors regarding unexpected user input should be handled. What if the user enters a
stringwhere you expeceted anint? What if the user inputs an unexpected control or escape key? - Inefficient Code - Correct code that puts unecessary strain on the processor or server. Consider networking in all codes application.
-
Document TODOs - If code includes
TODOcomments, ensure those comments are documented either in new issues or somewhere else, don't allow the code to be too cluttered withTODOcomments. -
Avoid submitting general game ideas or possible enhancements - Did the code submitted fulfill the issue it was connected to? Then your ideas for improvements belong in a new
enhancementissue.