Compare commits


No commits in common. 'master' and 'gh-pages' have entirely different histories.

  1. 30
  2. 14
  3. 14
  4. 43
  5. 108
  6. 84
  7. 445
  8. 21
  9. 20
  10. 7
  11. 28
  12. 35
  13. 33
  14. 86
  15. 40
  16. 22
  17. 12
  18. 20
  19. 231
  20. 11
  21. 0
  22. 98
  23. 8
  24. 13
  25. 1
  26. 62
  27. 674
  28. 661
  29. 53
  30. 99
  31. 174
  32. 674
  33. 15
  34. 553
  35. 229
  36. 92
  37. 583
  38. 583
  39. 6
  40. 22
  41. 157
  42. 624
  43. 1779
  44. 2109
  45. 160
  46. 171
  47. 882
  48. 1409
  49. 208
  50. 447
  51. 1746
  52. 996
  53. 818
  54. 47
  55. 1207
  56. 279
  57. 2562
  58. 2191
  59. 23
  60. 1835
  61. 1367
  62. 362
  63. 364
  64. 365
  65. 980
  66. 347
  67. 990
  68. 1726
  69. 111
  70. 329
  71. 470
  72. 535
  73. 573
  74. 478
  75. 604
  76. 651
  77. 300
  78. 47
  79. 58
  80. 1168
  81. 639
  82. 291
  83. 252
  84. 8576
  85. 461
  86. 755
  87. 1552
  88. 818
  89. 13296
  90. 317
  91. 1087
  92. 296
  93. 414
  94. 402
  95. 412
  96. 1534
  97. 3494
  98. 744
  99. 6356
  100. 579


@ -1,30 +0,0 @@


@ -1,14 +0,0 @@
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
indent_style = space
indent_size = 2
indent_style = space


@ -1,14 +0,0 @@
#Ignores big formatting commits when checking blame.
#To make use of this file by default, run 'git config blame.ignoreRevsFile .git-blame-ignore-revs'
#in the project folder
## Line ending conversions
# Force LF line endings with gitattributes and convert repo
# Line ending apocalypse
# Initial pass to convert LF to CRLF
# Many changes


@ -1,43 +0,0 @@
* text=auto
## Enforce text mode and LF line breaks
*.bat text eol=lf
*.css text eol=lf
*.css text eol=lf
*.dm text eol=lf
*.dme text eol=lf
*.dmf text eol=lf
*.htm text eol=lf
*.html text eol=lf
*.html text eol=lf
*.js text eol=lf
*.json text eol=lf
*.jsx text eol=lf
*.md text eol=lf
*.py text eol=lf
*.scss text eol=lf
*.sh text eol=lf
*.sql text eol=lf
*.svg text eol=lf
*.ts text eol=lf
*.tsx text eol=lf
*.txt text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
## Enforce binary mode
*.bmp binary
*.dll binary
*.dmb binary
*.exe binary
*.gif binary
*.jpg binary
*.png binary
*.so binary
## Merger hooks, run tools/hooks/install.bat or to set up
*.dmm text eol=lf merge=dmm
*.dmi binary merge=dmi
## Force changelog merging to use union
html/changelog.html text eol=lf merge=union


@ -1,108 +0,0 @@
# dmdoc
[DMDOC] is a documentation generator for DreamMaker, the scripting language
of the [BYOND] game engine. It produces simple static HTML files based on
documented files, macros, types, procs, and vars.
We use **dmdoc** to generate [DOCUMENTATION] for our code, and that documentation
is automatically generated and built on every new commit to the master branch
This gives new developers a clickable reference [DOCUMENTATION] they can browse to better help
gain understanding of the /tg/station codebase structure and api reference.
## Documenting code on /tg/station
We use block comments to document procs and classes, and we use `///` line comments
when documenting individual variables.
It is required that all new code be covered with DMdoc code, according to the [Requirements](#Required)
We also require that when you touch older code, you must document the functions that you
have touched in the process of updating that code
### Required
A class *must* always be autodocumented, and all public functions *must* be documented
All class level defined variables *must* be documented
Internal functions *should* be documented, but may not be
A public function is any function that a developer might reasonably call while using
or interacting with your object. Internal functions are helper functions that your
public functions rely on to implement logic
### Documenting a proc
When documenting a proc, we give a short one line description (as this is shown
next to the proc definition in the list of all procs for a type or global
namespace), then a longer paragraph which will be shown when the user clicks on
the proc to jump to it's definition
* Short description of the proc
* Longer detailed paragraph about the proc
* including any relevant detail
* Arguments:
* * arg1 - Relevance of this argument
* * arg2 - Relevance of this argument
### Documenting a class
We first give the name of the class as a header, this can be omitted if the name is
just going to be the typepath of the class, as dmdoc uses that by default
Then we give a short oneline description of the class
Finally we give a longer multi paragraph description of the class and it's details
* # Classname (Can be omitted if it's just going to be the typepath)
* The short overview
* A longer
* paragraph of functionality about the class
* including any assumptions/special cases
### Documenting a variable/define
Give a short explanation of what the variable, in the context of the class, or define is.
/// Type path of item to go in suit slot
var/suit = null
## Module level description of code
Modules are the best way to describe the structure/intent of a package of code
where you don't want to be tied to the formal layout of the class structure.
On /tg/station we do this by adding markdown files inside the `code` directory
that will also be rendered and added to the modules tree. The structure for
these is deliberately not defined, so you can be as freeform and as wheeling as
you would like.
[Here is a representative example of what you might write](
## Special variables
You can use certain special template variables in DM DOC comments and they will be expanded
[DEFINE_NAME] - Expands to a link to the define definition if documented
[/mob] - Expands to a link to the docs for the /mob class
[/mob/proc/Dizzy] - Expands to a link that will take you to the /mob class and anchor you to the dizzy proc docs
[/mob/var/stat] - Expands to a link that will take you to the /mob class and anchor you to the stat var docs
You can customise the link name by using `[link name][link shorthand].`
eg. `[see more about dizzy here] [/mob/proc/Dizzy]`
This is very useful to quickly link to other parts of the autodoc code to expand
upon a comment made, or reasoning about code


@ -1,84 +0,0 @@
# This list auto requests reviews from the specified org members
# when a PR that modifies the file in question is opened
# This list is alphabetized by User -> Filename KEEP IT THAT WAY
# In the event that multiple org members are to be informed of changes
# to the same file or dir, add them to the end under Multiple Owners
# Cobby
/code/modules/reagents/ @ExcessiveUseOfCobblestone
/code/modules/research/designs/ @ExcessiveUseOfCobblestone
/code/modules/surgery/ @ExcessiveUseOfCobblestone
/code/game/objects/items/storage/ @ExcessiveUseOfCobblestone
/code/modules/jobs/job_types/ @ExcessiveUseOfCobblestone
/code/modules/jobs/job_types/ @ExcessiveUseOfCobblestone
# Cyberboss
/code/controllers/subsystem/ @Cyberboss
/code/controllers/subsystem/ @Cyberboss
/code/controllers/ @Cyberboss
/code/datums/helper_datums/ @Cyberboss
/code/datums/ @Cyberboss
/code/datums/ @Cyberboss
/code/datums/ @Cyberboss
/code/modules/admin/verbs/ @Cyberboss
/code/modules/admin/verbs/ @Cyberboss
/code/modules/mapping/ @Cyberboss
# Jared-Fogle
/code/modules/unit_tests/ @Jared-Fogle
# Jordie0608
/SQL/ @Jordie0608
/code/controllers/subsystem/ @Jordie0608
/tools/SQLAlertEmail/ @Jordie0608
# LemonInTheDark
/code/__DEFINES/ @LemonInTheDark
/code/modules/atmospherics/ @LemonInTheDark
# MrStonedOne
/SQL/database_changelog.txt @MrStonedOne
/code/__DEFINES/ @MrStonedOne
/code/controllers/ @MrStonedOne
/code/controllers/ @MrStonedOne
/code/controllers/ @MrStonedOne
/code/controllers/ @MrStonedOne
/code/controllers/subsystem/ @MrStonedOne
# ninjanomnom
/code/__DEFINES/dcs/ @ninjanomnom
/code/controllers/subsystem/ @ninjanomnom
/code/controllers/subsystem/ @ninjanomnom
/code/datums/components/ @ninjanomnom
/code/datums/elements/ @ninjanomnom
/code/modules/shuttle/ @ninjanomnom
# ShizCalev
/_maps/ @ShizCalev
/sound/ @ShizCalev
# stylemistake
/code/__DEFINES/ @stylemistake
/code/__DEFINES/ @stylemistake
/code/controllers/subsystem/ @stylemistake
/code/controllers/subsystem/ @stylemistake
/code/modules/tgchat @stylemistake
/code/modules/tgui @stylemistake
/code/modules/tgui_panel @stylemistake
/tgui @stylemistake
# Multiple Owners
/icons/ @Twaticus @ShizCalev
/code/controllers/subsystem/ @LemonInTheDark @MrStonedOne
/code/modules/hydroponics/grown/ @optimumtact


@ -1,445 +0,0 @@
## Reporting Issues
If you ever encounter a bug in-game, the best way to let a coder know about it is with our GitHub Issue Tracker. Please make sure you use the supplied issue template, and include the round ID for the server.
(If you don't have an account, making a new one takes only one minute.)
If you have difficulty, ask for help in the #coding-general channel on our discord.
## Introduction
Hello and welcome to /tg/station's contributing page. You are here because you are curious or interested in contributing - thank you! Everyone is free to contribute to this project as long as they follow the simple guidelines and specifications below; at /tg/station, we strive to maintain code stability and maintainability, and to do that, we need all pull requests to hold up to those specifications. It's in everyone's best interests - including yours! - if the same bug doesn't have to be fixed twice because of duplicated code.
First things first, we want to make it clear how you can contribute (if you've never contributed before), as well as the kinds of powers the team has over your additions, to avoid any unpleasant surprises if your pull request is closed for a reason you didn't foresee.
## Getting Started
/tg/station doesn't have a list of goals and features to add; we instead allow freedom for contributors to suggest and create their ideas for the game. That doesn't mean we aren't determined to squash bugs, which unfortunately pop up a lot due to the deep complexity of the game. Here are some useful starting guides, if you want to contribute or if you want to know what challenges you can tackle with zero knowledge about the game's code structure.
If you want to contribute the first thing you'll need to do is [set up Git]( so you can download the source code.
After setting it up, optionally navigate your git commandline to the project folder and run the command: 'git config blame.ignoreRevsFile .git-blame-ignore-revs'
We have a [list of guides on the wiki]( that will help you get started contributing to /tg/station with Git and Dream Maker. For beginners, it is recommended you work on small projects like bugfixes at first. If you need help learning to program in BYOND, check out this [repository of resources](
There is an open list of approachable issues for [your inspiration here](
You can of course, as always, ask for help on the discord channels, or the forums, We're just here to have fun and help out, so please don't expect professional support.
## Meet the Team
The Headcoder is responsible for controlling, adding, and removing maintainers from the project. In addition to filling the role of a normal maintainer, they have sole authority on who becomes a maintainer, as well as who remains a maintainer and who does not.
Maintainers are quality control. If a proposed pull request doesn't meet the following specifications, they can request you to change it, or simply just close the pull request. Maintainers are required to give a reason for closing the pull request.
Maintainers can revert your changes if they feel they are not worth maintaining or if they did not live up to the quality specifications.
## Specifications
As mentioned before, you are expected to follow these specifications in order to make everyone's lives easier. It'll save both your time and ours, by making sure you don't have to make any changes and we don't have to ask you to. Thank you for reading this section!
### Object Oriented Code
As BYOND's Dream Maker (henceforth "DM") is an object-oriented language, code must be object-oriented when possible in order to be more flexible when adding content to it. If you don't know what "object-oriented" means, we highly recommend you do some light research to grasp the basics.
### All BYOND paths must contain the full path
(i.e. absolute pathing)
DM will allow you nest almost any type keyword into a block, such as:
varname1 = 1
varname1 = 0
The use of this is not allowed in this project as it makes finding definitions via full text searching next to impossible. The only exception is the variables of an object may be nested to the object, but must not nest further.
The previous code made compliant:
varname1 = 0
### No overriding type safety checks
The use of the : operator to override type safety checks is not allowed. You must cast the variable to the proper type.
### Type paths must begin with a /
eg: `/datum/thing`, not `datum/thing`
### Type paths must be snake case
eg: `/datum/thing/blue_bird`, not `datum/thing/BLUEBIRD` or `datum/thing/BlueBird` or `datum/thing/Bluebird` or `datum/thing/blueBird`
### Datum type paths must began with "datum"
In DM, this is optional, but omitting it makes finding definitions harder.
### Do not use text/string based type paths
It is rarely allowed to put type paths in a text format, as there are no compile errors if the type path no longer exists. Here is an example:
var/path_type = /obj/item/baseball_bat
var/path_type = "/obj/item/baseball_bat"
### Use var/name format when declaring variables
While DM allows other ways of declaring variables, this one should be used for consistency.
### Tabs, not spaces
You must use tabs to indent your code, NOT SPACES.
(You may use spaces to align something, but you should tab to the block level first, then add the remaining spaces)
### No hacky code
Hacky code, such as adding specific checks, is highly discouraged and only allowed when there is ***no*** other option. (Protip: 'I couldn't immediately think of a proper way so thus there must be no other option' is not gonna cut it here! If you can't think of anything else, say that outright and admit that you need help with it. Maintainers exist for exactly that reason.)
You can avoid hacky code by using object-oriented methodologies, such as overriding a function (called "procs" in DM) or sectioning code into functions and then overriding them as required.
### No duplicated code
Copying code from one place to another may be suitable for small, short-time projects, but /tg/station is a long-term project and highly discourages this.
Instead you can use object orientation, or simply placing repeated code in a function, to obey this specification easily.
### Startup/Runtime tradeoffs with lists and the "hidden" init proc
First, read the comments in [this BYOND thread](, starting where the link takes you.
There are two key points here:
1) Defining a list in the variable's definition calls a hidden proc - init. If you have to define a list at startup, do so in New() (or preferably Initialize()) and avoid the overhead of a second call (Init() and then New())
2) It also consumes more memory to the point where the list is actually required, even if the object in question may never use it!
Remember: although this tradeoff makes sense in many cases, it doesn't cover them all. Think carefully about your addition before deciding if you need to use it.
### Prefer `Initialize()` over `New()` for atoms
Our game controller is pretty good at handling long operations and lag, but it can't control what happens when the map is loaded, which calls `New` for all atoms on the map. If you're creating a new atom, use the `Initialize` proc to do what you would normally do in `New`. This cuts down on the number of proc calls needed when the world is loaded. See here for details on `Initialize`:
While we normally encourage (and in some cases, even require) bringing out of date code up to date when you make unrelated changes near the out of date code, that is not the case for `New` -> `Initialize` conversions. These systems are generally more dependant on parent and children procs so unrelated random conversions of existing things can cause bugs that take months to figure out.
### No magic numbers or strings
This means stuff like having a "mode" variable for an object set to "1" or "2" with no clear indicator of what that means. Make these #defines with a name that more clearly states what it's for. For instance:
There's no indication of what "1" and "2" mean! Instead, you'd do something like this:
This is clearer and enhances readability of your code! Get used to doing it!
### Control statements
(if, while, for, etc)
* All control statements must not contain code on the same line as the statement (`if (blah) return`)
* All control statements comparing a variable to a number should use the formula of `thing` `operator` `number`, not the reverse (eg: `if (count <= 10)` not `if (10 >= count)`)
### Use early return
Do not enclose a proc in an if-block when returning on a condition is more feasible
This is bad:
if (thing1)
if (!thing2)
if (thing3 == 30)
do stuff
This is good:
if (!thing1)
if (thing2)
if (thing3 != 30)
do stuff
This prevents nesting levels from getting deeper then they need to be.
### Use our time defines
The codebase contains some defines which will automatically multiply a number by the correct amount to get a number in deciseconds. Using these is preffered over using a literal amount in deciseconds.
The defines are as follows:
This is bad:
if(do_after(mob, 15))
This is good:
if(do_after(mob, 1.5 SECONDS))
### Develop Secure Code
* Player input must always be escaped safely, we recommend you use stripped_input in all cases where you would use input. Essentially, just always treat input from players as inherently malicious and design with that use case in mind
* Calls to the database must be escaped properly - use sanitizeSQL to escape text based database entries from players or admins, and isnum() for number based database entries from players or admins.
* All calls to topics must be checked for correctness. Topic href calls can be easily faked by clients, so you should ensure that the call is valid for the state the item is in. Do not rely on the UI code to provide only valid topic calls, because it won't.
* Information that players could use to metagame (that is, to identify round information and/or antagonist type via information that would not be available to them in character) should be kept as administrator only.
* It is recommended as well you do not expose information about the players - even something as simple as the number of people who have readied up at the start of the round can and has been used to try to identify the round type.
* Where you have code that can cause large-scale modification and *FUN*, make sure you start it out locked behind one of the default admin roles - use common sense to determine which role fits the level of damage a function could do.
### Files
* Because runtime errors do not give the full path, try to avoid having files with the same name across folders.
* File names should not be mixed case, or contain spaces or any character that would require escaping in a uri.
* Files and path accessed and referenced by code above simply being #included should be strictly lowercase to avoid issues on filesystems where case matters.
### SQL
* Do not use the shorthand sql insert format (where no column names are specified) because it unnecessarily breaks all queries on minor column changes and prevents using these tables for tracking outside related info such as in a connected site/forum.
* All changes to the database's layout(schema) must be specified in the database changelog in SQL, as well as reflected in the schema files
* Any time the schema is changed the `schema_revision` table and `DB_MAJOR_VERSION` or `DB_MINOR_VERSION` defines must be incremented.
* Queries must never specify the database, be it in code, or in text files in the repo.
* Primary keys are inherently immutable and you must never do anything to change the primary key of a row or entity. This includes preserving auto increment numbers of rows when copying data to a table in a conversion script. No amount of bitching about gaps in ids or out of order ids will save you from this policy.
### Mapping Standards
* TGM Format & Map Merge
* All new maps submitted to the repo through a pull request must be in TGM format (unless there is a valid reason present to have it in the default BYOND format.) This is done using the [Map Merge]( utility included in the repo to convert the file to TGM format.
* Likewise, you MUST run Map Merge prior to opening your PR when updating existing maps to minimize the change differences (even when using third party mapping programs such as FastDMM.)
* Failure to run Map Merge on a map after using third party mapping programs (such as FastDMM) greatly increases the risk of the map's key dictionary becoming corrupted by future edits after running map merge. Resolving the corruption issue involves rebuilding the map's key dictionary; id est rewriting all the keys contained within the map by reconverting it from BYOND to TGM format - which creates very large differences that ultimately delay the PR process and is extremely likely to cause merge conflicts with other pull requests.
* Variable Editing (Var-edits)
* While var-editing an item within the editor is perfectly fine, it is preferred that when you are changing the base behavior of an item (how it functions) that you make a new subtype of that item within the code, especially if you plan to use the item in multiple locations on the same map, or across multiple maps. This makes it easier to make corrections as needed to all instances of the item at one time as opposed to having to find each instance of it and change them all individually.
* Subtypes only intended to be used on away mission or ruin maps should be contained within a .dm file with a name corresponding to that map within `code\modules\awaymissions` or `code\modules\ruins` respectively. This is so in the event that the map is removed, that subtype will be removed at the same time as well to minimize leftover/unused data within the repo.
* Please attempt to clean out any dirty variables that may be contained within items you alter through var-editing. For example, due to how DM functions, changing the `pixel_x` variable from 23 to 0 will leave a dirty record in the map's code of `pixel_x = 0`. Likewise this can happen when changing an item's icon to something else and then back. This can lead to some issues where an item's icon has changed within the code, but becomes broken on the map due to it still attempting to use the old entry.
* Areas should not be var-edited on a map to change it's name or attributes. All areas of a single type and it's altered instances are considered the same area within the code, and editing their variables on a map can lead to issues with powernets and event subsystems which are difficult to debug.
### User Interfaces
* All new player-facing user interfaces must use TGUI.
* Raw HTML is permitted for admin and debug UIs.
* Documentation for TGUI can be found at:
* [tgui/](../tgui/
* [tgui/](../tgui/docs/
### Other Notes
* Code should be modular where possible; if you are working on a new addition, then strongly consider putting it in its own file unless it makes sense to put it with similar ones (i.e. a new tool would go in the "" file)
* Bloated code may be necessary to add a certain feature, which means there has to be a judgement over whether the feature is worth having or not. You can help make this decision easier by making sure your code is modular.
* You are expected to help maintain the code that you add, meaning that if there is a problem then you are likely to be approached in order to fix any issues, runtimes, or bugs.
* Do not divide when you can easily convert it to multiplication. (ie `4/2` should be done as `4*0.5`)
* If you used regex to replace code during development of your code, post the regex in your PR for the benefit of future developers and downstream users.
* Changes to the `/config` tree must be made in a way that allows for updating server deployments while preserving previous behaviour. This is due to the fact that the config tree is to be considered owned by the user and not necessarily updated alongside the remainder of the code. The code to preserve previous behaviour may be removed at some point in the future given the OK by maintainers.
* The dlls section of tgs3.json is not designed for dlls that are purely `call()()`ed since those handles are closed between world reboots. Only put in dlls that may have to exist between world reboots.
#### Enforced not enforced
The following coding styles are not only not enforced at all, but are generally frowned upon to change for little to no reason:
* English/British spelling on var/proc names
* Color/Colour - both are fine, but keep in mind that BYOND uses `color` as a base variable
* Spaces after control statements
* `if()` and `if ()` - nobody cares!
### Operators
#### Spacing
(this is not strictly enforced, but more a guideline for readability's sake)
* Operators that should be separated by spaces
* Boolean and logic operators like &&, || <, >, ==, etc (but not !)
* Bitwise AND &
* Argument separator operators like , (and ; when used in a forloop)
* Assignment operators like = or += or the like
* Operators that should not be separated by spaces
* Bitwise OR |
* Access operators like . and :
* Parentheses ()
* logical not !
Math operators like +, -, /, *, etc are up in the air, just choose which version looks more readable.
#### Use
* Bitwise AND - '&'
* Should be written as ```bitfield & bitflag``` NEVER ```bitflag & bitfield```, both are valid, but the latter is confusing and nonstandard.
* Associated lists declarations must have their key value quoted if it's a string
* WRONG: list(a = "b")
* RIGHT: list("a" = "b")
### Dream Maker Quirks/Tricks
Like all languages, Dream Maker has its quirks, some of them are beneficial to us, like these
#### In-To for-loops
```for(var/i = 1, i <= some_value, i++)``` is a fairly standard way to write an incremental for loop in most languages (especially those in the C family), but DM's ```for(var/i in 1 to some_value)``` syntax is oddly faster than its implementation of the former syntax; where possible, it's advised to use DM's syntax. (Note, the ```to``` keyword is inclusive, so it automatically defaults to replacing ```<=```; if you want ```<``` then you should write it as ```1 to some_value-1```).
HOWEVER, if either ```some_value``` or ```i``` changes within the body of the for (underneath the ```for(...)``` header) or if you are looping over a list AND changing the length of the list then you can NOT use this type of for-loop!
### for(var/A in list) VS for(var/i in 1 to list.len)
The former is faster than the latter, as shown by the following profile results:
Code used for the test in a readable format:
#### Istypeless for loops
A name for a differing syntax for writing for-each style loops in DM. It's NOT DM's standard syntax, hence why this is considered a quirk. Take a look at this:
var/list/bag_of_items = list(sword, apple, coinpouch, sword, sword)
for(var/obj/item/sword/S in bag_of_items)
if(!best_sword || S.damage > best_sword.damage)
best_sword = S
The above is a simple proc for checking all swords in a container and returning the one with the highest damage, and it uses DM's standard syntax for a for-loop by specifying a type in the variable of the for's header that DM interprets as a type to filter by. It performs this filter using ```istype()``` (or some internal-magic similar to ```istype()``` - this is BYOND, after all). This is fine in its current state for ```bag_of_items```, but if ```bag_of_items``` contained ONLY swords, or only SUBTYPES of swords, then the above is inefficient. For example:
var/list/bag_of_swords = list(sword, sword, sword, sword)
for(var/obj/item/sword/S in bag_of_swords)
if(!best_sword || S.damage > best_sword.damage)
best_sword = S
specifies a type for DM to filter by.
With the previous example that's perfectly fine, we only want swords, but here the bag only contains swords? Is DM still going to try to filter because we gave it a type to filter by? YES, and here comes the inefficiency. Wherever a list (or other container, such as an atom (in which case you're technically accessing their special contents list, but that's irrelevant)) contains datums of the same datatype or subtypes of the datatype you require for your loop's body,
you can circumvent DM's filtering and automatic ```istype()``` checks by writing the loop as such:
var/list/bag_of_swords = list(sword, sword, sword, sword)
for(var/s in bag_of_swords)
var/obj/item/sword/S = s
if(!best_sword || S.damage > best_sword.damage)
best_sword = S
Of course, if the list contains data of a mixed type then the above optimisation is DANGEROUS, as it will blindly typecast all data in the list as the specified type, even if it isn't really that type, causing runtime errors.
#### Dot variable
Like other languages in the C family, DM has a ```.``` or "Dot" operator, used for accessing variables/members/functions of an object instance.
var/mob/living/carbon/human/H = YOU_THE_READER
However, DM also has a dot variable, accessed just as ```.``` on its own, defaulting to a value of null. Now, what's special about the dot operator is that it is automatically returned (as in the ```return``` statement) at the end of a proc, provided the proc does not already manually return (```return count``` for example.) Why is this special?
With ```.``` being everpresent in every proc, can we use it as a temporary variable? Of course we can! However, the ```.``` operator cannot replace a typecasted variable - it can hold data any other var in DM can, it just can't be accessed as one, although the ```.``` operator is compatible with a few operators that look weird but work perfectly fine, such as: ```.++``` for incrementing ```.'s``` value, or ```.[1]``` for accessing the first element of ```.```, provided that it's a list.
## Globals versus static
DM has a var keyword, called global. This var keyword is for vars inside of types. For instance:
thing = TRUE
This does NOT mean that you can access it everywhere like a global var. Instead, it means that that var will only exist once for all instances of its type, in this case that var will only exist once for all mobs - it's shared across everything in its type. (Much more like the keyword `static` in other languages like PHP/C++/C#/Java)
Isn't that confusing?
There is also an undocumented keyword called `static` that has the same behaviour as global but more correctly describes BYOND's behaviour. Therefore, we always use static instead of global where we need it, as it reduces suprise when reading BYOND code.
## Pull Request Process
There is no strict process when it comes to merging pull requests. Pull requests will sometimes take a while before they are looked at by a maintainer; the bigger the change, the more time it will take before they are accepted into the code. Every team member is a volunteer who is giving up their own time to help maintain and contribute, so please be courteous and respectful. Here are some helpful ways to make it easier for you and for the maintainers when making a pull request.
* Make sure your pull request complies to the requirements outlined here
* You are going to be expected to document all your changes in the pull request. Failing to do so will mean delaying it as we will have to question why you made the change. On the other hand, you can speed up the process by making the pull request readable and easy to understand, with diagrams or before/after data.
* We ask that you use the changelog system to document your change, which prevents our players from being caught unaware by changes - you can find more information about this [on this wiki page](
* If you are proposing multiple changes, which change many different aspects of the code, you are expected to section them off into different pull requests in order to make it easier to review them and to deny/accept the changes that are deemed acceptable.
* If your pull request is accepted, the code you add no longer belongs exclusively to you but to everyone; everyone is free to work on it, but you are also free to support or object to any changes being made, which will likely hold more weight, as you're the one who added the feature. It is a shame this has to be explicitly said, but there have been cases where this would've saved some trouble.
* Please explain why you are submitting the pull request, and how you think your change will be beneficial to the game. Failure to do so will be grounds for rejecting the PR.
* If your pull request is not finished make sure it is at least testable in a live environment. Pull requests that do not at least meet this requirement will be closed. You may request a maintainer reopen the pull request when you're ready, or make a new one.
* While we have no issue helping contributors (and especially new contributors) bring reasonably sized contributions up to standards via the pull request review process, larger contributions are expected to pass a higher bar of completeness and code quality *before* you open a pull request. Maintainers may close such pull requests that are deemed to be substantially flawed. You should take some time to discuss with maintainers or other contributors on how to improve the changes.
## Porting features/sprites/sounds/tools from other codebases
If you are porting features/tools from other codebases, you must give them credit where it's due. Typically, crediting them in your pull request and the changelog is the recommended way of doing it. Take note of what license they use though, porting stuff from AGPLv3 and GPLv3 codebases are allowed.
Regarding sprites & sounds, you must credit the artist and possibly the codebase. All /tg/station assets including icons and sound are under a [Creative Commons 3.0 BY-SA license]( unless otherwise indicated. However if you are porting assets from GoonStation or usually any assets under the [Creative Commons 3.0 BY-NC-SA license]( are to go into the 'goon' folder of the /tg/station codebase.
## Banned content
Do not add any of the following in a Pull Request or risk getting the PR closed:
* National Socialist Party of Germany content, National Socialist Party of Germany related content, or National Socialist Party of Germany references
* Code where one line of code is split across mutiple lines (except for multiple, separate strings and comments; in those cases, existing longer lines must not be split up)
* Code adding, removing, or updating the availability of alien races/species/human mutants without prior approval. Pull requests attempting to add or remove features from said races/species/mutants require prior approval as well.
* Code which violates GitHub's [terms of service](
Just because something isn't on this list doesn't mean that it's acceptable. Use common sense above all else.
## A word on Git
This repository uses `LF` line endings for all code as specified in the **.gitattributes** and **.editorconfig** files.
Unless overridden or a non standard git binary is used the line ending settings should be applied to your clone automatically.
Note: VSC requires an [extension]( to take advantage of editorconfig.


@ -1,21 +0,0 @@
There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at
Option 1:
Follow this:
Option 2: Download the source code as a zip by clicking the ZIP button in the
code tab of
(note: this will use a lot of bandwidth if you wish to update and is a lot of
hassle if you want to make any changes at all, so it's not recommended.)
Option 3: Download a pre-compiled nightly at (same caveats as option 2)
*Warning: option 4 is out of date, and not maintained, use at your own risk*
Option 4: Use our docker image that tracks the master branch (See commits for build status. Again, same caveats as option 2)
docker run -d -p <your port>:1337 -v /path/to/your/config:/tgstation/config -v /path/to/your/data:/tgstation/data tgstation/tgstation <dream daemon options i.e. -public or -params>


@ -1,20 +0,0 @@
name: Bug report
about: Create a report to help reproduce and fix the issue
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable -->
## Round ID:
If you discovered this issue from playing tgstation hosted servers:
[Round ID]: # (It can be found in the Status panel or retrieved from ! The round id let's us look up valuable information and logs for the round the bug happened.)-->
## Testmerges:
<!-- If you're certain the issue is to be caused by a test merge [OOC tab -> Show Server Revision], report it in the pull request's comment section rather than on the tracker(If you're unsure you can refer to the issue number by prefixing said number with #. The issue number can be found beside the title after submitting it to the tracker).If no testmerges are active, feel free to remove this section. -->
## Reproduction:
<!-- Explain your issue in detail, including the steps to reproduce it. Issues without proper reproduction steps or explanation are open to being ignored/closed by maintainers.-->
<!-- **For Admins:** Oddities induced by var-edits and other admin tools are not necessarily bugs. Verify that your issues occur under regular circumstances before reporting them. -->


@ -1,7 +0,0 @@
name: Feature request
about: Suggest an idea for this project
Feature requests are not handled in the repository. The best place to discuss these ideas would be on the /tg/station 13 forums here:


@ -1,28 +0,0 @@
/tg/station currently comes equipped with five maps.
* [BoxStation (default)](
* [MetaStation](
* [DeltaStation](
* [PubbyStation](
* [DonutStation](
All maps have their own code file that is in the base of the _maps directory. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility.
The map that will be loaded for the upcoming round is determined by reading data/next_map.json, which is a copy of the json files found in the _maps tree. If this file does not exist, the default map from config/maps.txt will be loaded. Failing that, BoxStation will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a json from _maps to data/next_map.json before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round.
If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file.
Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](
/tg/station supports loading away missions however they are disabled by default.
Map files for away missions are located in the _maps/RandomZLevels directory. Each away mission includes it's own code definitions located in /code/modules/awaymissions/mission_code. These files must be included and compiled with the server beforehand otherwise the server will crash upon trying to load away missions that lack their code.
To enable an away mission open `config/awaymissionconfig.txt` and uncomment one of the .dmm lines by removing the #. If more than one away mission is uncommented then the away mission loader will randomly select one the enabled ones to load.


@ -1,35 +0,0 @@
Welcome to this short guide to the POLICY config mechanism.
You are probably reading this guide because you have been informed your antagonist or ghost role needs to support policy configuration.
## Requirements
It is a requirement of /tg/station development that all ghost roles, antags, minor antags and event mobs of any kind must support the policy system when implemented.
## What is policy configuration
Policy configuration is a json file that the administrators of a server can edit, which contains a dictionary of keywords -> string message.
The policy text for a specific keyword should be displayed when relevant and appropriate, to allow server administrators to define the broad strokes of policy for some feature or mob.
It is okay to provide a default text when the config is not set, but you are required to provide the config in all cases of a ghost role or an antagonist, or minor event.
If you're in doubt about needing to support policy config, I suggest doing it anyway. This should replace all flavour text, ghost spawn messages and so forth that the player (i.e client) sees upon entering the role, mob, or feature that is meant to dictate how they are permitted to be played as/with.
## What does this mean?
Concretely, it means you need to display to the client taking control of the mob or ghost role a string of text, pulled via keyword from the policy config system.
You can access the string of text through the `get_policy(keyword)` proc, this takes a single keyword argument, which should be a text string unique to your feature.
This will return a configured string of text, or blank/null if no policy string is set.
This is also accessible to the user if they use `/client/verb/policy()` which will display to them a list of all the policy texts for keywords applicable to the mob, you can add/modify the list of keywords by modifying the `get_policy_keywords()` proc of a mob type where that is relevant. **If you cannot use the verb to get your policy at any point, the feature is considered to NOT be supported.**
### Relaying Specific Policy To Players, Example
Here is a simple example taken from the slime pyroclastic event to relay specific policy.
var/policy = get_policy(ROLE_PYROCLASTIC_SLIME)
if (policy)
to_chat(S, policy)
It's recommended to use a define for your policy keyword to make it easily changeable by a developer


@ -1,33 +0,0 @@
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull request process. -->
## About The Pull Request
<!-- Describe The Pull Request. Please be sure every change is documented or this can delay review and even discourage maintainers from merging your PR! -->
## Why It's Good For The Game
<!-- Please add a short description of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding. -->
## Changelog
add: Added new things
add: Added more things
del: Removed old things
tweak: tweaked a few things
balance: rebalanced something
fix: fixed a few things
soundadd: added a new sound thingy
sounddel: removed an old sound thingy
imageadd: added some icons and images
imagedel: deleted some icons and images
spellcheck: fixed a few typos
code: changed some code
refactor: refactored some code
config: changed some config setting
admin: messed with admin stuff
server: something server ops should know
<!-- Both :cl:'s are required for the changelog to work! You can put your name to the right of the first :cl: if you want to overwrite your GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. -->


@ -1,86 +0,0 @@
First-time installation should be fairly straightforward. First, you'll need
BYOND installed. You can get it from Once you've done
that, extract the game files to wherever you want to keep them. This is a
sourcecode-only release, so the next step is to compile the server files.
Open tgstation.dme by double-clicking it, open the Build menu, and click
compile. This'll take a little while, and if everything's done right you'll get
a message like this:
saving tgstation.dmb (DEBUG mode)
tgstation.dmb - 0 errors, 0 warnings
If you see any errors or warnings, something has gone wrong - possibly a corrupt
download or the files extracted wrong. If problems persist, ask for assistance
in irc://
Once that's done, open up the config folder. You'll want to edit config.txt to
set the probabilities for different gamemodes in Secret and to set your server
location so that all your players don't get disconnected at the end of each
round. It's recommended you don't turn on the gamemodes with probability 0,
except Extended, as they have various issues and aren't currently being tested,
so they may have unknown and bizarre bugs. Extended is essentially no mode, and
isn't in the Secret rotation by default as it's just not very fun.
You'll also want to edit config/admins.txt to remove the default admins and add
your own. "Game Master" is the highest level of access, and probably the one
you'll want to use for now. You can set up your own ranks and find out more in
The format is
byondkey = Rank
where the admin rank must be properly capitalised.
This codebase also depends on a native library called rust-g. A precompiled
Windows DLL is included in this repository, but Linux users will need to build
and install it themselves. Directions can be found at the [rust-g
Finally, to start the server, run Dream Daemon and enter the path to your
compiled tgstation.dmb file. Make sure to set the port to the one you
specified in the config.txt, and set the Security box to 'Safe'. Then press GO
and the server should start up and be ready to join. It is also recommended that
you set up the SQL backend (see below).
To update an existing installation, first back up your /config and /data folders
as these store your server configuration, player preferences and banlist.
Then, extract the new files (preferably into a clean directory, but updating in
place should work fine), copy your /config and /data folders back into the new
install, overwriting when prompted except if we've specified otherwise, and
recompile the game. Once you start the server up again, you should be running
the new version.
If you'd like a more robust server hosting option for tgstation and its
derivatives. Check out our server tools suite at
The SQL backend requires a Mariadb server running 10.2 or later. Mysql is not supported but Mariadb is a drop in replacement for mysql. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here:
If you are hosting a testing server on windows you can use a standalone version of MariaDB pre load with a blank (but initialized) tgdb database. Find them here: Just unzip and run for a working (but insecure) database server. Includes a zipped copy of the data folder for easy resetting back to square one.
Web delivery of game resources makes it quicker for players to join and reduces some of the stress on the game server.
1. Edit to set the `PRELOAD_RSC` define to `0`
1. Add a url to config/external_rsc_urls pointing to a .zip file containing the .rsc.
* If you keep up to date with /tg/ you could reuse /tg/'s rsc cdn at Otherwise you can use cdn services like CDN77 or cloudflare (requires adding a page rule to enable caching of the zip), or roll your own cdn using route 53 and vps providers.
* Regardless even offloading the rsc to a website without a CDN will be a massive improvement over the in game system for transferring files.
Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified
IRC channel/server, see the /tools/minibot folder for more


@ -1,40 +0,0 @@
name: Compile changelogs
- cron: "0 0 * * *"
name: "Compile changelogs"
runs-on: ubuntu-latest
- name: "Setup python"
uses: actions/setup-python@v1
python-version: '3.x'
- name: "Install deps"
run: |
python -m pip install --upgrade pip
python -m pip install pyyaml
sudo apt-get install dos2unix
- name: "Checkout"
uses: actions/checkout@v1
fetch-depth: 25
- name: "Compile"
run: |
python tools/ html/changelog.html html/changelogs
- name: "Convert Lineendings"
run: |
unix2dos html/changelogs/.all_changelog.yml
- name: Commit
run: |
git config --local ""
git config --local "Changelogs"
git pull origin master
git commit -m "Automatic changelog compile [ci skip]" -a || true
- name: "Push"
uses: ad-m/github-push-action@master
github_token: ${{ secrets.GITHUB_TOKEN }}


@ -1,22 +0,0 @@
name: Docker Build
- master
runs-on: ubuntu-latest
- uses: actions/checkout@v2
- name: Build and Publish Docker Image to Registry
uses: elgohr/Publish-Docker-Github-Action@master
name: tgstation/tgstation
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
dockerfile: Dockerfile
tags: "latest"
cache: true


@ -1,12 +0,0 @@
name: "Round ID Linker"
types: [opened]
runs-on: ubuntu-latest
- uses: tgstation/round_linker@master
repo-token: ${{ secrets.GITHUB_TOKEN }}


@ -1,20 +0,0 @@
name: Mark stale issues and pull requests
- cron: "0 0 * * *"
runs-on: ubuntu-latest
- uses: actions/stale@v1
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: "This PR has been inactive for long enough to be automatically marked as stale. This means it is at risk of being auto closed in ~ 7 days, please address any outstanding review items and ensure your PR is finished, if these are all true and you are auto-staled anyway, you need to actively ask maintainers if your PR will be merged. Once you have done any of the previous actions then you should request a maintainer remove the stale label on your PR, to reset the stale timer. If you feel no maintainer will respond in that time, you may wish to close this PR youself, while you seek maintainer comment, as you will then be able to reopen the PR yourself"
days-before-stale: 7
days-before-close: 7
stale-pr-label: 'Stale'
exempt-pr-label: 'RED LABEL'


@ -1,231 +0,0 @@
###Files and folders specified here will never be tracked.
#Ignore everything in datafolder and subdirectories
#Ignore byond config folder.
#Ignore compiled files and other files generated during compilation.
# temporary files which can be created if a process still has a handle open of a deleted file
# KDE directory preferences
# Linux trash folder which might appear on any partition or disk
# swap
# session
# temporary
# auto-generated tag files
# Byte-compiled / optimized / DLL files
# C extensions
# Distribution / packaging
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
# Installer logs
# Unit test / coverage reports
# Translations
# Django stuff:
# Flask instance folder
# Scrapy stuff:
# Sphinx documentation
# PyBuilder
# IPython Notebook
# pyenv
# celery beat schedule file
# dotenv
# virtualenv
# IntelliJ IDEA / PyCharm (with plugin)
# Spyder project settings
# Rope project settings
# Windows image file caches
# Folder config file
# Recycle Bin used on file shares
# Windows Installer files
# Windows shortcuts
# Icon must end with two \r
# Thumbnails
# Files that might appear in the root of a volume
# Directories potentially created on remote AFP share
Network Trash Folder
Temporary Items
#Visual studio stuff
#GitHub Atom
#KDevelop and Kate
#extra map stuff
#dmdoc default folder
# Ignore custom music and title screens (amend as appropriate)
#Linux docker


@ -1,11 +0,0 @@
stage: build
- tgui/**/*.js
- tgui/**/*.scss
when: always
image: node:lts
- tgui/bin/tgui --ci

config/external_rsc_urls.txt → .nojekyll


@ -1,98 +0,0 @@
language: generic
os: linux
dist: bionic
- ___TGS3TempBranch
- ___TGSTempBranch
- name: "Run Linters"
- python3
- python3-pip
- python3-setuptools
- pcregrep
- rustc
- cargo
- $HOME/SpacemanDMM
- tools/travis/
- tools/travis/ dreamchecker
- tools/travis/ tgstation.dme
- tools/travis/
- find . -name "*.php" -print0 | xargs -0 -n1 php -l
- find . -name "*.json" -not -path "*/node_modules/*" -print0 | xargs -0 python3 ./tools/
- tools/travis/
- tools/travis/
- ~/dreamchecker
- name: "Compile All Maps"
- libstdc++6:i386
- tools/travis/
- source $HOME/BYOND/byond/bin/byondsetup
- tools/travis/
- name: "Compile and Run Tests"
mariadb: '10.2'
- ubuntu-toolchain-r-test
- libstdc++6:i386
- gcc-multilib
- g++-7
- g++-7-multilib
- libssl1.1:i386
- zlib1g:i386
- tools/travis/
- source $HOME/BYOND/byond/bin/byondsetup
- tools/travis/
- mysql -u root -e 'CREATE DATABASE tg_travis;'
- mysql -u root tg_travis < SQL/tgstation_schema.sql
- mysql -u root -e 'CREATE DATABASE tg_travis_prefixed;'
- mysql -u root tg_travis_prefixed < SQL/tgstation_schema_prefixed.sql
- tools/travis/ -DTRAVISBUILDING tgstation.dme || travis_terminate 1
- tools/travis/
- name: "Generate Documentation"
# Only run for non-PR commits to the real master branch.
if: branch = master AND head_branch IS blank
- tools/travis/ dmdoc
# Travis checks out a hash, try to get back on a branch.
- git checkout $TRAVIS_BRANCH || true
- ~/dmdoc
- touch dmdoc/.nojekyll
provider: pages
skip_cleanup: true
local_dir: dmdoc


@ -1,8 +0,0 @@
"recommendations": [


@ -1,13 +0,0 @@
"eslint.workingDirectories": [
"workbench.editorAssociations": [
"filenamePattern": "*.dmi",
"viewType": "imagePreview.previewEditor"
"files.eol": "\n"


@ -0,0 +1 @@


@ -1,62 +0,0 @@
FROM tgstation/byond:513.1528 as base
FROM base as rust_g
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git \
WORKDIR /rust_g
RUN apt-get install -y --no-install-recommends \
libssl-dev \
pkg-config \
curl \
gcc-multilib \
&& curl -sSf | sh -s -- -y --default-host i686-unknown-linux-gnu \
&& git init \
&& git remote add origin
RUN /bin/bash -c "source \
&& git fetch --depth 1 origin \$RUST_G_VERSION" \
&& git checkout FETCH_HEAD \
&& ~/.cargo/bin/cargo build --release
FROM base as dm_base
WORKDIR /tgstation
FROM dm_base as build
COPY . .
RUN DreamMaker -max_errors 0 tgstation.dme \
&& tools/ /deploy \
&& rm /deploy/*.dll
FROM dm_base
RUN apt-get update \
&& apt-get install -y --no-install-recommends software-properties-common \
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get dist-upgrade -y \
&& apt-get install -y --no-install-recommends \
libmariadb2 \
mariadb-client \
libssl1.0.0 \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /root/.byond/bin
COPY --from=rust_g /rust_g/target/release/ /root/.byond/bin/rust_g
COPY --from=build /deploy ./
VOLUME [ "/tgstation/config", "/tgstation/data" ]
ENTRYPOINT [ "DreamDaemon", "tgstation.dmb", "-port", "1337", "-trusted", "-close", "-verbose" ]


@ -1,674 +0,0 @@
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.