ENIGMA:Guidelines_for_master_branch - hpgDesigns/hpgdesigns-dev.io GitHub Wiki

Guidelines for changes to the master branch.

The idea behind these guidelines is to help developers and contributors, old as new, making good decisions in regards to the master branch of the repository. It is based off common thought and experience between the developers, and is not meant to be fast and hard rules, but informing and guiding developers. It should be noted that "developers" and "contributors" are used interchangeably in these guidelines.

Change notes:

2013-06-06: Added information on how to use git and GitHub to handle changes. 2013-06-04: Creation of this document.

Purpose of these guidelines

  • Create common perspective amongst developers on the purpose of the master branch and how to deal with changes to it.
  • Help make developers aware of some of the possible issues that changes can create.
  • Inform and guide developers in regards to how to deal with changes.

The purpose of the master branch of enigma-dev/enigma-dev

The master branch is the generally used branch by both developers and users. Having a common branch enables quick fixing and development, and means users will not have to wait long before getting the newest additions or fixes. Given that ENIGMA is still not fully mature or feature complete, it makes sense to have a semi-stable main branch, which will rarely break games relying on core and established functionality, while still allowing quick development and experimentation on unstable and non-core parts. However, if the master branch breaks core or established functionality all the time, the master branch becomes very unstable for users, and developers will waste time on finding and fixing issues that used to be non-issues. For this reason, it is important to keep the master branch at least semi-stable, rarely breaking core or established functionality.

Possible issues with changes

  • Buggy changes that cause regressions, either silently or loudly, resulting in runtime crashes, very poor performance, compile-time errors, etc. These are the most common types of issues, and can often be prevented by testing it with the relevant configurations.
  • Changes that handles an issue in one subsystem, but does not handle the same issue in other subsystems of its kind. These changes can be bothersome, because it may cause confusion about whether an issue has really been handled, and it takes time to determine where the issue is handled. Frequently, a lot of time can be saved later by ensuring that the issue is handled in all relevant subsystems, or at least creating an issue on the tracker that describes where the issue has been handled and not handled.
  • Changes that depends on specific tools and technologies, which can take considerable amounts of work to fix, especially if time pass and more and more of the code depends on it. Some of these changes are necessary and acceptable, for instance when making platform-specific changes in an isolated platform subsystem. Main ways to avoid or handle such issues is to follow standards when available, isolate technology dependencies in specific systems (OpenGL{1,3}, DirectX, OpenAL, SFML Audio, etc.) and using them through generic interfaces, and simply coding things in a way that is fully or mostly independent of the technology or tool used (using common subset of available features amongst main Make build tools). Another way is also to put off using bleeding edge features until support is mature and widely available.
  • Architecture and interface changes affect how the different systems interact. Bad interfaces decreases modularity and increases coupling and dependencies amongst systems, and generally make it more difficult to debug, test and develop systems. It can be difficult to determine or predict whether an interface will be good or bad, so thinking about and discussing important systems, as well as developing for change, is generally advisable. Isolating dependent code between systems in "bridges" is one way to decrease coupling in certain cases.

Dealing with changes

When you are in doubt about a change, and whether it should be committed to the master branch, there are several options for dealing with that:

  • The first is to test the change out for relevant scenarios. This is often quite effective, and it is therefore recommended that you always do at least light testing of your change, but you should take care to test with all the relevant configurations. For instance, if you change the interface for a subsystem like Collisions, it is a good idea to test that each collision subsystem still compiles and works with the new interface. That said, testing does not cover everything, and it can sometimes be difficult to test things, but testing for simple compilation and running is generally useful and easy. The main exception is testing of different platforms; in these cases, it is a very good idea to get others to test the changes.
  • Taking time to look at the changes, investigating them, looking through them, etc., can be laborious but quite effective. It can also help to improve the changes themselves. This should be always be done to some degree when working on established and core features, to avoid easily avoidable issues.
  • Experiment! Make the change in a fork or a branch other than master, and experiment and work with it. If the system is not yet established and known to people not to be ready for use yet, you can also do experimentation directly in master. Just be careful not to do experimentation outside of the specific system.
  • Implement the change in a fork or branch, and get others to look at it. This takes the time of others, but may well save time down the road. This is very appropriate for changes that could cause considerable issues if faulty, especially if you have already tested, experimented and/or investigated the changes thoroughly.
  • Low-severity changes are much less risky to commit than high-severity changes.

When determining whether a change should be committed to the main branch, it is useful to determine what issues it has. However, it can be difficult to determine all the issues of a given change. To handle this, there are some general guidelines for estimating the potential severity of possible issues of a change.

  • If a change is fully isolated to a subsystem, getting the change wrong will only affect that subsystem and other systems that depend on that subsystem (directly or indirectly). The more systems that depend upon a given subsystem, the more things it can break.
  • Systems and features that are used by most users and developers directly or indirectly, such as most of the stuff in Universal_System, the graphics system OpenGL1, or the Precise collision system, will affect many. Conversely, systems that are only occasionally used (like the audio system, the None collision system, the datetime extension, or the particles extension), and which aren't depended upon by any other systems, will not affect nearly as many. As long as they still compile or are not by default on, breaking them does is not as severe. That said, breaking such system and letting them stay broken can cause problems down the line, and since they are used less, issues will generally be found and reported relatively later.
  • Unstable parts that aren't used and aren't meant to be used, will not affect users or developers other than the ones working on it.
  • Issues that prevent compilation or running games with ENIGMA at all are quite severe. It is generally easy to test for these issues, since if it compiles and runs, then it shouldn't be a problem. The main issue is if the changes has platform-specific parts. Testing for several different platforms can be bothersome or impossible, depending on hardware. Use a fork or a branch to share and have an easier time with testing or in order to get others to test on the platforms you do not have access to that it really does not break things.
  • Platform-specific issues can be bothersome to find, debug and fix. Therefore, a platform-specific issue is generally more severe than a non-platform-specific change when all else is equal.
  • Changes that deal with interfaces and architecture can have long-term issues, and they can be difficult to test. Thinking about them and discussing them with others is generally recommended to help ensure that the changes are good, as well as seeking to make a flexible design that allows correcting some mistakes in the interface. A good thumb of rule is that the less dependencies and the less coupled the changes make the interface, the less that can go wrong.
  • If there are parts of the potential issues that you are not confident you know sufficiently about, determining the severity can be difficult. Learning more about those parts and related topics can be recommended, as well as asking others for advise on the topics as well as the changes in question.
  • One other factor to consider is the severity of the alternatives. If the change is definitely better than the current status, it may be better to commit and describe the uncertainties regarding the changes, such that they can be looked at later by yourself and others.

Using git to handle changes

git offers several features which can be used to handle changes. One of these features are branches. See http://gitref.org/branching/ for information about what a branch is. In regards to changes, the master branch is the main branch used by users and developers alike. By creating and using a separate branch from the master branch, you can do any changes you want without it bothering anyone else, and let others look at it, possibly fix any issues, and then merge it into master.

For examples on how to use branches, see post 1 and post 2.

Using GitHub to handle changes

Another feature is the fork of GitHub, which you can find more information about here: https://help.github.com/articles/fork-a-repo. Basically, a fork creates a whole new repository based on the new one, where you can do any changes you want, and once you would like others to look at it or get it merged into the main repository, you can make a pull request where you describe the changes and other relevant details. If more work is needed, you can make more commits, and it will be reflected in the pull request.