There is a plenty of reference material about `polymake` API, classes, and coding conventions. To help you with the orientation, we have listed some typical development tasks accompanied with design suggestions and recommended reading. The cases are introduced in the order of increasing (at our opinion) complexity.

- A new object construction (like a cube or prism):
  depending on the complexity of the algorithm and on efficiency considerations, you can choose to implement it either as a C++ client or directly as a user function in perl.
  - If you decide to write a client, you should start with the client tutorial. The most relevant reference material is put together under the "Client Programs" navigation topic, first of all the communication API, the Template Library, and tips about Makefile setup.
    As soon as you get your client compiled and tested, you can move it to one of your favourite locations for executables (listed in PATH) or install it together with the standard `polymake` clients, provided you have the write access to the installation directory.
  - If you choose the implementation in perl, you should get acquainted with the general rule file syntax, since the user functions have to be defined in the rule files. Furthermore, you will need to learn the Poly::Object interface, at least how to get object properties.
    We don't recommend to put the user functions into the standard `polymake` rule files, as they will be unavoidably overwritten by the next `polymake` update. Create your own collection of rule files instead, and store its location in your file ~/.polymake/prefer.pl (at the beginning of this file you will find detailed instructions how to do it). `polymake` will automatically load your rules.
- A new algorithm as a (partial) replacement of a standard `polymake` rule (say, a new convex hull algorithm):
  Like in the previous paragraph, it can be implemented either as a C++ client or directly in perl. However, to enforce the new algorithm to be taken instead of a standard one, you must first write a production rule around it. In the case of a client, the body of the rule will consist of a single line calling a Modules::client function.
  Then you must make your new rule the preferred one. It can be done by giving it a preference label or a smaller weight than that of the standard rule. Refer to the convex hull rules (rule file apps/polytope/rational.rules) as an elaborated example. If your algorithm should be preferred only for some special kinds of input data, you may supply the rule with the means of dynamical control: preconditions, variable weight, or both.
  To say it again, keep your rules separate from the standard ones.
- A new property of the object:
  First of all, you should choose a suitable property type and declare the property in your rule file. Then you have to write one or more production rules creating this property, as described in the previous paragraph.
  You may choose to declare your property temporary if its representation is too big to be stored permanently in the data file, or the computations are so easy that it doesn't hurt to repeat them each time the property is needed.
- A new object method:
  Object methods are mainly used for two purposes. The first one is very close to the idea of temporary properties, that is, they perform some computation, but don't store the results in the data file. Usually they print the results to STDOUT instead. For this kind of methods you should be familiar with the Poly::Object interface and the rule file syntax.
  The second large group of object methods do some visualization of the objects. If you are going to develop a new visualization method, you should additionally get acquainted with the family of perl classes implementing graphical primitives, such as Visual::Polygon or Visual::Graph. They aren't currently described in this documentation, you will have to learn on examples scattered over visual.rules in the `polymake` applications and modules. Your task becomes yet more complicated if the standard graphical primitives don't suffice your needs (say, you need circles or curves.) Then you have not only to implement the new graphical primitives (which must be always derived from Visual::Object), but also define corresponding draw methods in the visualization back-ends capable to display them. The examples in javaview.rules or postscript.rules should give you an initial idea how these methods look like.
- An interface to an external software package:
  The form of the interface depends on the capabilities of the package and on the role it should play for a `polymake` user.
  - using the software to compute object properties:
    You will need a production rule, which prepares the input data, writes them into a temporary file, runs some executable, reads the results from another temporary file (you might want to study perl regular expressions closer, man perlre ), and converts them back to `polymake` representation.
    If the external program works like a filter, that is, reads from stdin and writes to stdout, then you can spare the temporary files and communicate with the program using Poly::ProgramPipe class.
  - preparing the input for independent software, which is to be run later:
    In this case you should write a user method, which creates a non-temporary input file for the software. The file name can be passed as an argument or automatically derived from the object name. An example of such method is fundamental_group, which prepares an input file for GAP.
  - visualization software:
    Here you can find the first approximation to the description of the internal visualization interface in polymake. Since it is not complete, you will have to study the code of the existing visualization back-ends, such as Geomview or Postscript packages. Don't be discouraged by the size of this code, the minimal requirements for a visualization back-end are very moderate.
  If you are going to distribute your rule file to other people working on different computers, you should include a autoconfiguration section, which checks the presence of the software package. This will prevent your customers from puzzling about error messages coming deep from the rule code. In the most cases a simple check with find_via_path suffices.
- A new object type:
  Technically the introduction of a new object type is easy: it is a one-line declaration. But this can be a difficult design decision.
  A new object type can be either independent or derived from another existing object type. An independent object type should be introduced as soon as a new mathematical object appears on stage, which is rich in own properties and can't be modeled well using the existing types without loss of clarity or mathematical correctness. Examples would be hyperplane arragements in the application polytope or knots in the application topaz.
  A derived object type, on the contrary, should be only introduced with the aim to refine some concept or solve a representation problem. As long as you can add new properties to an existing object type without creating contradictions, you should do so. Even if you are working with a large family of objects with magnificent classification of (mathematical) subtypes and special cases, you can still model it adequately using such features as rule preconditions and undefined property values.
  For example, the application polytope purposely does not define special types for unbouded polyhedra or simplicial polytopes; they are much simpler expressed by boolean properties, and those rules which are applicable only to bounded or simplicial polytopes state this constraint by appropriate pre-condition expressions.
  But there are two object types, RationalPolytope and FloatPolytope, which differ in the representation of the point coordinates (exact and flating-point, respectively) It is clear, that both representations can't co-exist in the same object without endangering its consistency, therefore for each object one allowed representation must be chosen from its very birth. Dividing the polytopes into these two subtypes is the most natural technical solution for these requirement.
  Having once declared a new object type, you should remember to switch to its package each time you want to add new properties, rules, or methods belonging to the new type.
- A new application:
  You can found a new application if you have the feeling that plenty of the new objects and algorithms you have developed have nothing or very little to do with existing applications. There is no strict law about when to start with a new application. You can perfectly go on populating a standard application with dozens of new types, but you can have equally perfect reasons to found an application with a single object type in it.
  The technical part of the task is rather easy. You create a hierarchy of directories rooted at apps/NEW_NAME similar to any of the standard application, that is, include and src with C++ sources, rules with rule files, perllib with perl modules etc. Then you rerun make configure in order to create the build directory for the new application and populate it with necessary Makefile files.
  If you have ventured so far to write a new application, you might be interested in supporting tools like automated test environment and documentation generator. They are not included in the public distribution; please contact the development team in order to get them.