-
Notifications
You must be signed in to change notification settings - Fork 2
Styling Guide and Best Practices for Studio 7
Reasons to have a styling guide in place:
- We will have hundreds of files by the end of sprint 4
- Faster to find files
- Easier to infer meaning from others' code
- Easier to diagnose issues in others' code
- Ensures new code follows the same structural/conceptual practices used already
- We become better at determining merge conflict solutions
- Assets are named using "snake_case". This is to separate them from Java src files that use "PascalCase".
- "RETROACTIVE.png" is incorrect
- "retroactive.png" is the most correct
- "boxBoy.png" is incorrect
- "box_boy.png" is the most correct
-
Character sprites should have their own folder under assets/images/characters/*. If a character atlas falls into a set of alternative, similar atlases, its members should have a 2-digit suffix, starting at 00.
- "boy0.atlas" is incorrect
- "boy_0.atlas" is also incorrect
- "boy_00.atlas" is the most correct
*: this is due to the sheer number of (likely unnecessary) character files in main. If less are used, then they could share images/characters/ instead.
-
Assets used for rendering objects (e.g. bed, door, tree, tv) should have their own folder under assets/images/objects/**. If an object atlas falls into a set of alternative, similar atlases, its members should have a 2-digit numerical suffix, starting at 00.
**: we can accept all object files sharing the same objects/ directory if the majority prefers it to excessive structuring
- Describing assets with their orientation should be done using North, South, East and/or West. Animations should use "ing" verbs where applicable. Files part of the same animation should have a 1-digit suffix, starting at 0. This convention is the same for declaring animations in .atlas files.
-
"boy_01_stand_up.png" is incorrect
-
"boy_01_stand_north.png" is correct if the context prefers "stand" over "standing"
-
"boy_01_standing_north.png" is the most correct when describing animations
-
For complex directions, "boy_01_standing_north_east.png" is almost correct
-
"boy_01_standing_northeast.png" is the most correct
-
For animation files of the same animation, "boy_01_standing_north_00.png" is almost correct
-
"boy_01_standing_north_0.png" is the most correct
-
-
Assets relating to tile textures should fall into assets/images/tiles under one of hex/, iso/, or ortho/. Such files should be prefixed with the folder they fall under.
- "Why not separate tiles by 'grass' or 'wall' instead?" That structure would leave giant tilesets like tiles/ortho/ortho_terrain_set.png in a weird position.
- "ortho/terrain_set.png" is not correct. In a larger context, this can get confusing if you are could have used "hex/terrain_set.png" but refer to them both as "terrain_set.png"
- "ortho/ortho_terrain_set.png" is the most correct
-
Assets loaded specifically for usage in
UIComponent
s should have their own folder under assets/images/ui/.
-
All classes extending
Component
should be packaged alongside the classes that implement them, inside their own components/ folder.- Components commonly used in classes extending
Entity
can be found in src/.../entities/components/, for example. - Exceptions to this rule include: src/.../screens
- One screen usually has many unique
UIComponents
, so it is cleaner to have them packaged alongside each other instead of src/.../screens/components holding so many unique components.
- One screen usually has many unique
- Components commonly used in classes extending
-
Components that are used in more than one type of class should fall into a higher-level package, such as src/.../physics/components/
- These components usually just their own package by having a lot of non-
Components
falling nicely into src/.../physics/. If not, they should fall under src/.../generic/ - Exceptions to this rule could include components that are HEAVILY associated with one class, but is used occasionally elsewhere
- These components usually just their own package by having a lot of non-
-
UIComponent
s should be suffixed with "Display". When viewing the file structure, this makes it easier to separate mostly-functional components from mostly-aesthetic ones.
Test packages should follow the exact same structure as src/main/com/deco2800/game/. This will take care of protected variables being unusable otherwise.
As standard in Java, constants follow "UPPER_SNAKE_CASE"
- e.g. ROOT_DIR, SETTINGS_FILE, WINDOW_WIDTH, WINDOW_HEIGHT
As standard in Java, variables follow "camelCase"
- e.g. logger, game, mainMenuTextures
As standard in Java, functions follow "camelCase"
- e.g. create(), earlyUpdate(), getEntity()
- Constructors using "PascalCase" is an exception due to Java file naming conventions
Not standardised anywhere, but events should use "snake_case"
- e.g. start, change_character, win_default, walking_north
WHY??
- Avoids navigation issues where events could share the same prefix/name as other variables or functions. It is much easier to find/replace all events if they follow this structure and avoids accidents like replacing function names.
- This is especially useful for atlases that already follow "snake_case" for referencing .png files and declaring animations. A simple search for the term "walking_north" will bring up instances in atlases and event names.
- Event names function much more similar to constants than other variables. Using underscores is more appropriate for this reason.
Starting in sprint 2, we will work together to implement the randomly-generated map system. Part of this feature requires that there are no dependencies on the order of objects procedurally generated.
- For example, a bed object shouldn't require references to other objects to initialise. If this was allowed, the map generation system will have to somehow pass the character reference to its constructor.
Therefore, interfaces should be used for interactions between objects in the game world.
- If implemented correctly, objects can interact with each other regardless of whether they know the object by class
- "Calling" objects only need to know what can be called in the interface, and "listening" objects only need to know what to do when called by anything
- As a result, the map generation can be done without having to pass an arbitrary number of object references to the objects it generates
- Objects can guarantee that they will load safely (and completely) in a contained environment
Look into how variables of unknown types are typed with interfaces like Drawable, Comparable, Iterable etc. on the internet for how this could work.
Entities and Components
Interaction System
Unit Testing
Input Handling
UI
Game Screens and Areas
Map Generation
Basic Interactable Objects Design