Skip to content

Styling Guide and Best Practices for Studio 7

Jantoom edited this page Sep 3, 2021 · 11 revisions

Introduction

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

File structuring

Files found in source/core/assets/

Structural and naming guidelines for assets

  • 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 images

  • 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.

Object images

  • 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

Orientation and animations

  • 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

Tile images

  • 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 UIComponents should have their own folder under assets/images/ui/.

Files found in source/core/src/main/

Structural and naming guidelines for Java files in src

  • 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.
  • 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
  • UIComponents should be suffixed with "Display". When viewing the file structure, this makes it easier to separate mostly-functional components from mostly-aesthetic ones.

Files found in source/core/src/test/

Test packages should follow the exact same structure as src/main/com/deco2800/game/. This will take care of protected variables being unusable otherwise.

Symbol declarations in .java files

Constants

As standard in Java, constants follow "UPPER_SNAKE_CASE"

  • e.g. ROOT_DIR, SETTINGS_FILE, WINDOW_WIDTH, WINDOW_HEIGHT

Variables

As standard in Java, variables follow "camelCase"

  • e.g. logger, game, mainMenuTextures

Functions

As standard in Java, functions follow "camelCase"

  • e.g. create(), earlyUpdate(), getEntity()
  • Constructors using "PascalCase" is an exception due to Java file naming conventions

Event names using the existing event system

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.

Conceptual Best Practices

Interfaces over components for object interaction

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.

Clone this wiki locally