# Project Instructions

- Always break functions into logical subfunctions. No long-scrolling functions, in any language. This applies to source code, scripts, build scripts, CMake, Makefiles, and similar project files. Preserve this subfunction splitting discipline during refactors.
- Modularity is non-negotiable. Always group logically related functions together into a module. Preserve modularity during refactors.
- Reuse or extend existing abstractions instead of duplicating logic wherever possible. Don't repeat yourself. The goal here is to prevent duplication. Not to discourage appropriate logical separation of prior abstractions into new logical abstractions where sensible.
- Always isolate configurable behaviour into configuration variables appropriate for the language and framework being used.
- Never bake in literals; at minimum, declare them at the top of the file with a semantically meaningful name.
- Don't add unnecessary getters and setters in classes. Just access member vars directly.
- Don't use hungarian notation in var names. Class member vars should not have prefixed or postfixed underscores. Instead do the inverse: use prefixed or postfixed underscores for auto-scoped var names when they shadow static or member var names.
- UI should be responsive. Always prefer to use pre-packaged UI toolkit widgets, containers and colour sets harmoniously, instead of writing custom CSS overrides. Write custom CSS only if there's no UI toolkit mechanism available.
- Aggressively isolate, split off, deduplicate and reuse code which can be made into common library code. Do the same with UI elements. Do this both when implementing new features and opportunistically while refactoring or changing old code/UI elements.
- Names of files, functions, classes, abstractions, database fields, etc should be aimed at disambiguating purpose and function, rather than at brevity.
- Any source or header file that includes a Boost header must include `<boostAsioLinkageFix.h>` first (at the top of the file, or immediately after the include guard in headers), before all other includes, so Boost.Asio is used as a non-header-only library correctly.
- When refactoring code, moving code around or splitting code into new files, don't omit or remove source code comments. Preserve source code comments across refactors.
- Do not omit or remove code comments when refactoruing code. Preserve code comments.

## Style:

* Project uses 4-char-width tabs for indentation.
* UpperCamelCase for class/struct names, lowerCamelCase for var and member var
  names; underscores_between_words for namespace names. No hungarian notation.
* Differentiate overshadowing local arg var names from class member var names
  by prefixing local arg var names with underscore (_). Don't do things like
  postfixing the local arg var name with "In", etc.
* Single-line blocks after a selection/iteration statement must always be
  enclosed in braces, but you can choose whether opening brace is on same line,
  versus whether you put both braces on same line. I.e:
	```
	if (...) {
		// Acceptable
	}
	if (...)
		{ /* Also acceptable */ }
	if (...)
		// But never do this anywhere.
  ```
* Multiline brace blocks always have opening brace on next line.
* Classes/structs:
	```
	class/struct MyClass
	// Opening brace always on next line.
	{
	public:
		void function();
	
	/* Member vars always go at the bottom of the class.
	 * always put a visibility marker before member vars begin.
	 */
	public:
		int memberVar1, memberVar2;
		/* When a member var's value is agnostic of its construction signature,
		 * use assignment in the class def to reduce code duplication and error
		 * surface.
		 */
		int memberVarWhoseDefaultValIsAgnosticOfConstruction = AGNOSTIC_DEFAULT_VAL;
	};

	class/struct MyClass
	// Base classes have tab after colon.
	:	public MyClassBase1, public MyClassBase2,
	// Tabulation persisted when base classes spill onto multiple lines.
		public MyClassBase3
	{
	};
	```
* Constructors:
	```
	MyCtor()
	// No tab after colon for member vars.
	: memberVar1(...), memberVar2(...)
	// If ctor body empty, just do braces together on their own line.
	{}

	MyCtor()
	// Base classes have a tab after the colon.
	:	MyCtorBase1(...), MyCtorBase2(...),
		// Base class tabulation continues for multi-line situations.
		MyCtorBase3(...)
	memberVar1(...), memberVar2(...)
	{}
	```
