The Modularization Handbook - S.P.L.U.R.T. Style, v1.0 
IntroductionWelcome to the S.P.L.U.R.T. codebase's modularization handbook! Our goal is to make contributing to our codebase as easy and comfy as possible for coders while upkeeping our code standards. We understand that maintaining a codebase that's a fork of another can be challenging, but with the right practices, we can keep our code clean, organized, and easy to manage. This handbook outlines our modularization protocols and coding standards to help you get started. If you'd like to know more about coding, contributing and contribution standards, feel free to read this repository's contribution guides! Important Note - Test Your Pull RequestsYou are responsible for testing your content. Please do not mark a pull request as ready for review until you have thoroughly tested it. If you need a separate client for testing, you can use a guest account by logging out of BYOND and connecting to your test server. Test merges are for stress tests, not for finding bugs that could have been caught with local testing. The Nature of ConflictsConflicts can arise when changes are made to the same lines of code in different branches. For example, if the original code is:
And we change it to:
But upstream changes it to:
This results in a conflict that needs to be resolved manually. Our solution is modularization. The Modularization ProtocolModularization is the practice of organizing code into separate, self-contained modules that can be developed, tested, and maintained independently. In the context of our codebase, this means placing as much as possible of the new code, icons, sounds, and other assets into the Our modularization protocols are founded on three pillars:
Modular OverridesModular overrides allow us to extend or modify the behavior of existing code without directly editing the core files. This is done by creating new definitions or modifying existing ones in a way that they can be easily integrated into the core codebase. There are two main types of modular overrides: Variable Overrides and Proc Overrides. Variable OverridesVariable overrides allow you to modify existing variables in a modular fashion. This is useful when you need to introduce new properties to existing objects without altering the core code. For example:
In this example, a new variable muzzle_flash is added to the /obj/item/gun object with a value of Proc OverridesProc overrides allow you to extend or modify the behavior of existing procedures (procs) without directly editing the core files. This is done by defining a new proc that calls the original proc and then adds the new behavior. For example:
In this example, the shoot_live_shot proc is overridden to add a new behavior (spawning sparks) after calling the original proc. This ensures that the new behavior is added without modifying the core code. How and Why Modular Overrides WorkModular overrides work by leveraging BYOND's file inclusion and proc definition order. When BYOND compiles the code, it processes files and definitions in the order that they're included in tgstation.dme. BYOND orders said includes in alphabetical order, with Proc overrides run in the order of last-defined to first-defined. This means that the most recently defined proc will be the one that is executed. By placing our overrides in files that are included later in the compilation process, we ensure that they take precedence over earlier definitions. Why modular_zzplurt?The folder is named When to Use Modular OverridesModular overrides should be used whenever possible to keep the core codebase clean and maintainable. However, it's important to use them judiciously and ensure that they do not introduce performance issues or make the code harder to understand and maintain. Specifically:
By following these guidelines, we can ensure that our codebase remains clean, maintainable, and easy to navigate, while still allowing for the flexibility to add new features and make necessary changes. Folder StructureInstead of using different modules for every different bit of the game, we prefer to use a structure that resembles the structure of the repo itself inside our modular folder. This means we have one coding folder for all the code, one icons folder, one sounds folder, etc.
Commenting ConventionsWhen making non-modular changes to the core code, please use the following commenting conventions or similar:
Modular DefinesOur modular defines are located at Binary Files and MapsIt's preferable to use modular binary files (sounds, icons, assets, etc.) to add content rather than editing non-modular binary files. This should always be your first option when working with binary files. However, if it is absolutely necessary, you may edit non-modular binary files. Remember, if you want to edit maps or binary files, you must install the hooks located in tools/hooks/install.bat. For sound files the only accepted format to use in the codebase is MapsWhen editing maps, especially those that exist in the upstream codebase, the first option should be to use the automapper. The automapper allows you to make modular edits to maps by applying changes through predefined templates and coordinates, ensuring that the core map files remain untouched. There are two main ways to use the automapper: the simple area automapper for small changes and the template automapper for larger changes.
Direct edits to the map files should only be made if the automapper is not sufficient for the intended edits. This ensures that our map changes remain modular and easier to manage. AfterwordWe hope this handbook makes contributing to S.P.L.U.R.T. a pleasant experience. Remember, these guidelines are here to help maintain the quality and organization of our codebase. If you have any questions or need assistance, don't hesitate to reach out to our maintainers or the community. Happy coding! |