From 5f86df885b0678542ab91ee2a2f1f4bc77973369 Mon Sep 17 00:00:00 2001 From: Alexis Date: Tue, 17 Feb 2026 15:28:12 -0500 Subject: [PATCH] Adds a modularity guide unique to Bubber (#5224) ## About The Pull Request Does as the title says. ## Why It's Good For The Game We've been using Skyrat's since we existed as a server. ## Proof Of Testing N/A ## Changelog N/A --- README.md | 2 +- {modular_skyrat => modular_zubbers}/readme.md | 192 ++++++------------ 2 files changed, 67 insertions(+), 127 deletions(-) rename {modular_skyrat => modular_zubbers}/readme.md (54%) diff --git a/README.md b/README.md index f7c4aa732c6..49829be7e14 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ | Website | Link | | ----------------------- | ----------------------------------------------------------------- | | Git / GitHub cheatsheet | https://www.notion.so/Git-GitHub-61bc81766b2e4c7d9a346db3078ce833 | -| Guide to Modularization | [./modular_skyrat/readme.md](./modular_skyrat/readme.md) | +| Guide to Modularization | [./modular_zubbers/readme.md](./modular_zubbers/readme.md) | | Website | https://wiki.bubberstation.org/index.php?title=Main_Page | | Code | https://github.com/Bubberstation/Bubberstation | | Wiki | https://tgstation13.org/wiki/Main_Page | diff --git a/modular_skyrat/readme.md b/modular_zubbers/readme.md similarity index 54% rename from modular_skyrat/readme.md rename to modular_zubbers/readme.md index b54f8539581..d0afb39f06a 100644 --- a/modular_skyrat/readme.md +++ b/modular_zubbers/readme.md @@ -1,27 +1,37 @@ -# The modularization handbook - Skyrat style, v0.2 +# The modularization handbook - Bubber style, v0.1 -## Failure to follow this guide will result in your PR being denied. +## Failure to follow this guide will result in you being asked to change your PR. ## Introduction -To develop and maintain a separate codebase is a big task, that many have failed and suffered the consequences of, such as outdated, and messy code. -It's not necessarily the fault of lack of skill of the people maintaining it, merely the lack of resources and how much continuous effort such an endeavor takes. +Developing and maintaining a separate codebase is a large complex project with lots of risk. -One of the solutions for such, is to base our server on a solid codebase, that is primarily maintained by somebody else, in this case tgstation, and insert our content in a modular fashion, while following the general code (but not gameplay) direction of the upstream, mirroring any changes they do for parity. +To deal with this, Bubberstation has chosen a solution of modularization, wherein the codebase is based on an upstream (/tg/station) where we pull core features and code from, and gain the benefit of mirroring any changes they perform on their codebase at parity. From there, we add our own content in a modular fashion which we are responsible for. -Git, as a version control system, is very useful, however it is just a very methodical thing, that follows its many algorithms, that sadly cannot always intelligently resolve certain changes in the code in an unambiguous way, giving us conflicts, that need to be resolved in a manual fashion. +This allows us to focus more on content and a customized experience, while also reducing a degree of overhead in maintenance effort. -Due to maintainability being one of the main reasons behind our rebase to another codebase, **this protocol will seriously be enforced.** -A well organized, documented and atomized code saves our maintainers a lot of headache, when being reviewed. -Don't dump on them the work that you could have done yourself. +It is important to note that Git as a tool for a version control system is very useful, but does come with the caveat that we need to carefully resolve code conflicts that come from our upstream source. -This document is meant to be updated and changed, whenever any new exceptions are added onto it. It might be worth it to check, from time to time, whether we didn't define a more unique standardized way of handling some common change. +This guide is intended to provide examples, guidance, and ultimately standards on how we manage our implementation of modularization. + +Considering that maintainability is one of the key reasons behind our rebase to another codebase, **this standard will be strictly enforced**. + +A well organized, documented and atomized code is the standard we want to set in order to reduce development time, debugging and general pain points. +It is important that contributors adhere to this standard, to the benefit of all. + +This document should be considered a living breathing document which can be changed and updated at any time. Considering reviewing it regularly, or even contributing! ## Important note - TEST YOUR PULL REQUESTS -You are responsible for the testing of your content. You should not mark a pull request ready for review until you have actually tested it. If you require 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 not for bug finding, they are for stress tests where local testing simply doesn't allow for this. +You are responsible for the testing of your content. You should not mark a pull request ready for review until you have actually tested it. You should ensure that you have evidence of testing your PR before submitting it. -### The nature of conflicts +For example: If you are adding a new hairstyle, have a short video of a character sporting your hairstyle in-game, showing off all angles of the hairstyle. Or a screenshot of all angles of the hairstyle taken from in-game. This shows that your PR runs, and that the hairstyle works and is selectable in-game to the people reviewing your PR. It also shows off the hairstyle to people wanting to see it. + +If you require 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 not for bug finding, they are for stress tests where local testing simply doesn't allow for this. + +### The nature of merge conflicts + +A merge conflict happens when your upstream pull commit is competing with your master or local branch commit. For example, let's have an original @@ -33,7 +43,7 @@ in the core code, that we decide to change from 1 to 2 on our end, ```diff - var/something = 1 -+ var/something = 2 //SKYRAT EDIT ++ var/something = 2 // BUBBER EDIT ``` but then our upstream introduces a change in their codebase, changing it from 1 to 4 @@ -46,7 +56,7 @@ but then our upstream introduces a change in their codebase, changing it from 1 As easy of an example as it is, it results in a relatively simple conflict, in the form of ```byond -var/something = 2 //SKYRAT EDIT +var/something = 4 // BUBBER EDIT ``` where we pick the preferable option manually. @@ -59,7 +69,7 @@ tl;dr it tries its best but ultimately is just a dumb program, therefore, we mus Our answer to this is modularization of the code. -**Modularization** means, that most of the changes and additions we do, will be kept in a separate **`modular_skyrat/`** folder, as independent from the core code as possible, and those which absolutely cannot be modularized, will need to be properly marked by comments, specifying where the changes start, where they end, and which feature they are a part of, but more on that in the next section. +**Modularization** means, that most of the changes and additions we do, will be kept in a separate **`modular_zubbers/`** folder, as independent from the core code as possible, and those which absolutely cannot be modularized, will need to be properly marked by comments, specifying where the changes start, where they end, and which feature they are a part of, but more on that in the next section. ## The modularization protocol @@ -67,18 +77,16 @@ Always start by thinking of the theme/purpose of your work. It's oftentimes a go **If it's a tgcode-specific tweak or bugfix, first course of action should be an attempt to discuss and PR it upstream, instead of needlessly modularizing it here.** -Otherwise, pick a new ID for your module. E.g. `DNA-FEATURE-WINGS` or `XENOARCHEAOLOGY` or `SHUTTLE_TOGGLE` - We will use this in future documentation. It is essentially your module ID. It must be uniform throughout the entire module. All references MUST be exactly the same. This is to allow for easy searching. +The best practice for modularization involves making a **`modular_zubbers/`** version of whatever file you may be working on and copying that path exactly for ease of finding it. For example, if your file is **`code/game/objects/items/crab17.dm`** then you would make your new file in **`modular_zubbers/code/game/objects/items/crab17.dm`**. Sometimes the folders you need may not exist already, it is perfectly fine to make new folders in order to ensure your modular file goes in the same file path as it does on /tg/ just with **`modular_zubbers/`** as the first folder. -And then you'll want to establish your core folder that you'll be working out of which is normally your module ID. E.g. `modular_skyrat/modules/shuttle_toggle` +New files go in **`modular_zubbers/`** as well, go with your heart as to which file to put them in if there are no exact file matches on /tg/, a personal suggestion would be to look at where _similar_ files go. + +**All files in `modular_skyrat/` are free to be edited as you please without need for modularization, however, file creations are restricted, as we aim to remove that folder eventually.** ### Maps -IMPORTANT: MAP CONTRIBUTION GUIDELINES HAVE BEEN UPDATED - When you are adding a new item to the map you MUST follow this procedure: -Start by deciding how big of a change it is going to be, if it is a small 1 item change, you should use the simple area automapper. If it is an entire room, you should use the template automapper. - -We will no longer have _skyrat map versions. +Start by deciding how big of a change it is going to be, if it is a small one item change, you should use the simple area automapper. If it is an entire room, you should use the template automapper. DO NOT CHANGE TG MAPS, THEY ARE HELD TO THE SAME STANDARD AS ICONS. USE THE ABOVE TO MAKE MAP EDITS. @@ -88,60 +96,30 @@ The simple area automapper uses datum entries to place down a single item in an ### Assets: images, sounds, icons and binaries -Git doesn't handle conflicts of binary files well at all, therefore changes to core binary files are absolutely forbidden, unless you have a really *really* ***really*** good reason to do otherwise. +Git doesn't handle conflicts of binary files well at all, therefore changes to core binary files are absolutely forbidden, unless you have a really _really_ **_really_** good reason to do otherwise. All assets added by us should be placed into the same modular folder as your code. This means everything is kept inside your module folder, sounds, icons and code files. -- ***Example:*** You're adding a new lavaland mob. +- **_Example:_** You're adding a new lavaland mob. - First of all you create your modular folder. E.g. `modular_skyrat/modules/lavalandmob` + First of all you create your modular folder. E.g. `modular_zubbers/code/modules/mob/living/basic/lavaland` - And then you'd want to create sub-folders for each component. E.g. `/code` for code and `/sounds` for sound files and `/icons` for any icon files. + And then you'd want to create new files and folders for each component. E.g. `modular_zubbers/sound/items/weapons` for sound files and `modular_zubbers/icons/mob/simple/lavaland` for any icon files. After doing this, you'll want to set your references within the code. ```byond - /mob/lavaland/newmob - icon = 'modular_skyrat/modules/lavalandmob/icons/mob.dmi' + /mob/living/basic/mining/new_mob + icon = 'modular_zubbers/icons/mob/simple/lavaland/lavaland_monsters.dmi' icon_state = "dead_1" - sound = 'modular_skyrat/modules/lavalandmob/sounds/boom.ogg' + sound = 'modular_zubbers/sound/items/weapons/bite.ogg' ``` This ensures your code is fully modular and will make it easier for future edits. - Other assets, binaries and tools, should usually be handled likewise, depending on the case-by-case context. When in doubt, ask a maintainer or other contributors for tips and suggestions. -- Any additional clothing icon files you add MUST go into the existing files in master_files clothing section. - -### The `master_files` Folder - -You should always put any modular overrides of icons, sound, code, etc. inside this folder, and it **must** follow the core code folder layout. - -Example: `code/modules/mob/living/living.dm` -> `modular_skyrat/master_files/code/modules/mob/living/living.dm` - -This is to make it easier to figure out what changed about a base file without having to search through proc definitions. - -It also helps prevent modules needlessly overriding the same proc multiple times. More information on these types of edits come later. - -### Fully modular portions of your code - -This section will be fairly straightforward, however, I will try to go over the basics and give simple examples, as the guide is aimed at new contributors likewise. - -The rule of thumb is that if you don't absolutely have to, you shouldn't make any changes to core codebase files. With some exceptions that will be mentioned shortly. - -In short, most of the modular code will be placed in the subfolders of your main module folder **`modular_skyrat/modules/yourmodule/code/`**, with similar rules as with the assets. Do not mirror core code folder structures inside your modular folder. - -For example, `modular_skyrat/modules/xenoarcheaology/code` containing all the code, tools, items and machinery related to it. - -Such modules, unless _very_ simple, **need** to have a `readme.md` in their folder, containing the following: - -- links to the PRs that implemented this module or made any significant changes to it -- short description of the module -- list of files changed in the core code, with a short description of the change, and a list of changes in other modular files that are not part of the same module, that were necessary for this module to function properly -- (optionally) a bit more elaborative documentation for future-proofing the code, that will be useful further development and maintenance -- credits - -***Template:*** [Here](module_template.md) +- Any additional clothing icon files you add MUST go into the existing files in either `modular_zubbers/icons/mob/clothing` for on_mob sprites or `modular_zubbers/icons/obj/clothing` for in-hand sprites. ## Modular Overrides (Important!!) @@ -149,7 +127,7 @@ Note, that it is possible to append code in front, or behind a core proc, in a m **Note about proc overrides: Just because you can, doesn't mean you should!!** -In general they are a good idea and encouraged whenever it is possible to do so. However this is not a hard rule, and sometimes Skyrat edits are preferable. Just try to use your common sense about it. +In general they are a good idea and encouraged whenever it is possible to do so. However this is not a hard rule, and sometimes Bubber edits are preferable. Just try to use your common sense about it. For example: please do not copy paste an entire TG proc into a modular override, make one small change, and then bill it as 'fully modular'. These procs are an absolute nightmare to maintain because once something changes upstream you have to update the overridden proc. @@ -157,9 +135,7 @@ Sometimes you aren't even aware the override exists if it compiles fine and does The best candidates for modular proc overrides are ones where you can just tack something on after calling the parent, or weave a parent call cleverly in the middle somewhere to achieve your desired effect. -Performance should also be considered when you are overriding a hot proc (like Life() for example), as each additional call adds overhead. Skyrat edits are much more performant in those cases. For most procs this won't be something you have to think about, though. - -### These modular overrides should be kept in `master_files`, and you should avoid putting them inside modules as much as possible. +Performance should also be considered when you are overriding a hot proc (like Life() for example), as each additional call adds overhead. Bubber edits are much more performant in those cases. For most procs this won't be something you have to think about, though. To keep it simple, let's assume you wanted to make guns spark when shot, for simulating muzzle flash or whatever other reasons, and you want potentially to use it with all kinds of guns. @@ -192,37 +168,35 @@ And that wraps the basics of it up. Every once in a while, there comes a time, where editing the core files becomes inevitable. -Please be sure to log these in the module readme.md. Any file changes. - In those cases, we've decided to apply the following convention, with examples: - **Addition:** ```byond - //SKYRAT EDIT ADDITION BEGIN - SHUTTLE_TOGGLE - (Optional Reason/comment) + // BUBBER EDIT - ADDITION - START - SHUTTLE_TOGGLE var/adminEmergencyNoRecall = FALSE var/lastMode = SHUTTLE_IDLE var/lastCallTime = 6000 - //SKYRAT EDIT ADDITION END + // BUBBER EDIT - ADDITION - END ``` - **Removal:** ```byond - //SKYRAT EDIT REMOVAL BEGIN - SHUTTLE_TOGGLE - (Optional Reason/comment) + // BUBBER EDIT - REMOVAL - START - SHUTTLE_TOGGLE /* for(var/obj/docking_port/stationary/S in stationary) if(S.id = id) return S */ - //SKYRAT EDIT REMOVAL END + // BUBBER EDIT - REMOVAL - END WARNING("couldn't find dock with id: [id]") ``` And for any removals that are moved to different files: ```byond - //SKYRAT EDIT REMOVAL BEGIN - SHUTTLE_TOGGLE - (Moved to modular_skyrat/shuttle_toggle/randomverbs.dm) + // BUBBER EDIT - REMOVAL - START - SHUTTLE_TOGGLE - (Moved to modular_zubbers/shuttle_toggle/randomverbs.dm) /* /client/proc/admin_call_shuttle() set category = "Admin - Events" @@ -244,16 +218,15 @@ In those cases, we've decided to apply the following convention, with examples: message_admins(span_adminnotice("[key_name_admin(usr)] admin-called the emergency shuttle.")) return */ - //SKYRAT EDIT REMOVAL END + // BUBBER EDIT - REMOVAL - END ``` - **Change:** ```byond - //SKYRAT EDIT CHANGE BEGIN - SHUTTLE_TOGGLE - (Optional Reason/comment) - //if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) - SKYRAT EDIT - ORIGINAL + // BUBBER EDIT - CHANGE - START - SHUTTLE_TOGGLE if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE, SHUTTLE_DISABLED) - //SKYRAT EDIT CHANGE END + // BUBBER EDIT - CHANGE - END return 1 ``` @@ -264,41 +237,12 @@ From every rule, there's exceptions, due to many circumstances. Don't think abou ### Defines Due to the way byond loads files, it has become necessary to make a different folder for handling our modular defines. -That folder is **`code/__DEFINES/~skyrat_defines`**, in which you can add them to the existing files, or create those files as necessary. +That folder is **`code/__DEFINES/~~bubber_defines`**, in which you can add them to the existing files, or create those files as necessary. If you have a define that's used in more than one file, it **must** be declared here. If you have a define that's used in one file, and won't be used anywhere else, declare it at the top, and `#undef MY_DEFINE` at the bottom of the file. This is to keep context menus clean, and to prevent confusion by those using IDEs with autocomplete. -### Module folder layout - -To keep form and ensure most modules are easy to navigate and to keep control of the amount of files and folders being made in the repository, you are required to follow this layout. - -Ensure the folder names are exactly as stated. - -Top most folder: module_id - -**DO NOT COPY THE CORE CODE FILE STRUCTURE IN YOUR MODULE!!** - -**Code**: Any .DM files must go in here. - -- Good: /modular_skyrat/modules/example_module/code/disease_mob.dm -- Bad: /modular_skyrat/modules/example_module/code/modules/antagonists/disease/disease_mob.dm - -**Icons**: Any .DMI files must go in here. - -- Good: /modular_skyrat/modules/example_module/icons/mining_righthand.dmi -- Bad: /modular_skyrat/modules/example_module/icons/mob/inhands/equipment/mining_righthand.dmi - -**Sound**: Any SOUND files must go in here. - -- Good: See above. -- Bad: See above. - -The readme should go into the parent folder, module_id. - -**DO NOT MIX AND MATCH FILE TYPES IN FOLDERS!** - ### Commenting out code - DON'T DO IT If you are commenting out redundant code in modules, do not comment it out, instead, delete it. @@ -312,30 +256,30 @@ This also applies to files, do not comment out entire files, just delete them in ## Modular TGUI TGUI is another exceptional case, since it uses javascript and isn't able to be modular in the same way that DM code is. -ALL of the tgui files are located in `/tgui/packages/tgui/interfaces` and its subdirectories; there is no specific folder for Skyrat UIs. +ALL of the tgui files are located in `/tgui/packages/tgui/interfaces` and its subdirectories; there is no specific folder for Bubber UIs. ### Modifying upstream files When modifying upstream TGUI files the same rules apply as modifying upstream DM code, however the grammar for comments may be slightly different. -You can do both `// SKYRAT EDIT` and `/* SKYRAT EDIT */`, though in some cases you may have to use one over the other. +You can do both `// BUBBER EDIT` and `/* BUBBER EDIT */`, though in some cases you may have to use one over the other. In general try to keep your edit comments on the same line as the change. Preferably inside the JSX tag. e.g: ```js ``` ```js ``` @@ -343,31 +287,27 @@ In general try to keep your edit comments on the same line as the change. Prefer ``` -If that is not possible, you can wrap your edit in curly brackets e.g. +If that is not possible, you can wrap your edit in curly brackets e.g. ```js -{/* SKYRAT EDIT ADDITION START */} - - someProp="whatever" - -{/* SKYRAT EDIT ADDITION END */} +{ + /* BUBBER EDIT - ADDITION - START */ +} +someProp="whatever"; +{ + /* BUBBER EDIT - ADDITION - END */ +} ``` -### Creating new TGUI files +### Creating new TGUI files **IMPORTANT! When creating a new TGUI file from scratch, please add the following at the very top of the file (line 1):** + ```js -// THIS IS A SKYRAT UI FILE +// THIS IS A BUBBER UI FILE ``` -This way they are easily identifiable as modular TGUI .tsx/.jsx files. You do not have to do anything further, and there will never be any need for a Skyrat edit comment in a modular TGUI file. - -## Exemplary PR's - -Here are a couple PR's that are great examples of the guide being followed, reference them if you are stuck: - -- -- +This way they are easily identifiable as modular TGUI .tsx/.jsx files. You do not have to do anything further, and there will never be any need for a Bubber edit comment in a modular TGUI file. ## Afterword