summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/coding-style.rst284
-rw-r--r--doc/core/index.rst37
-rw-r--r--doc/dev-process.rst43
-rw-r--r--doc/index.rst46
-rw-r--r--doc/introduction.rst43
-rw-r--r--doc/submitting-patches.rst142
6 files changed, 595 insertions, 0 deletions
diff --git a/doc/coding-style.rst b/doc/coding-style.rst
new file mode 100644
index 0000000..68c2240
--- /dev/null
+++ b/doc/coding-style.rst
@@ -0,0 +1,284 @@
+Rune Engine coding style
+========================
+
+This is a short document describing the preferred coding style for the Rune
+Engine. This coding style is largely inspired by the Linux kernel coding style,
+with some tweaks to make it friendly to modern editors.
+
+Indentation
+-----------
+
+Tabs are 8 spaces, tab characters should not be used. This makes the code look
+the same across editors and systems, and forces developers to simplify their
+code wherever possible. Large indentations make each code block easier to
+identify at a glance.
+
+.. code-block:: c
+
+ int main(int argc, char* argv[]) {
+ if (rune_init(argc, argv) != 0) {
+ log_output(LOG_FATAL, "Error!");
+ return -1;
+ }
+
+ int running = 1;
+ while (running) {
+ // main loop
+ }
+
+ rune_exit();
+ }
+
+Branch statements should not be placed on the same line; it makes it look like
+you have something to hide:
+
+.. code-block:: c
+
+ if (condition) do_this;
+ do_something_always;
+
+Braces should be used on multiple statements:
+
+.. code-block:: c
+
+ if (condition) {
+ do_this();
+ do_that();
+ }
+
+Assignments should be placed on their own lines. The coding style is very simple
+and fancy expressions are frowned upon.
+
+Long lines
+----------
+
+The preferred limit on the length of a single line is 80 columns, however, some
+exceptions are made based on readability. Otherwise, lines longer than 80
+columns should ideally be broken down into sensible chunks. A commonly used
+technique is to align descendants to a function open parenthesis. However,
+user-visible strings should *never* be broken as that breaks the ability to grep
+for them.
+
+Braces and spaces
+-----------------
+
+The opening brace should *always* be placed last on the same line and the
+closing brace first on the following line. This applies to all functions and
+statement blocks. If a statement is followed by a continuation, it is placed
+right after the brace. This allows easy insertion and deletion of interposing
+statements:
+
+.. code-block:: c
+
+ int func(void) {
+ }
+
+ switch (value) {
+ case 0:
+ break;
+ default:
+ return;
+ }
+
+ if (x == 1) {
+ here();
+ then_here();
+ over_there_as_well();
+ } else {
+ do_this();
+ }
+
+An exception is when a single statement under a branch: no braces are required
+unless one of the branches has multiple lines. In addition, braces should be
+used on any loop that has more than a single statement.
+
+Spaces should be placed on each side of most binary and ternary operators, such
+as the following:
+
+.. code-block:: c
+
+ = + - < > * / % | & ^ <= >= == != ? :
+
+However, spaces should *not* be placed after unary operators, increment and
+decrement operators and structure member access operators.
+
+Unnecessary whitespace at the end of lines or files is frowned upon. Some
+editors with smart indentation will leave whitespace at the beginning of new
+lines so you can start typing the next line right away. However, many editors
+do not erase the whitespace should you choose not to continue typing.
+
+Git will warn about trailing whitespace, and can optionally strip it out for
+you; however, if applying a series of patches, this may make later patches in
+the series fail by changing context lines.
+
+Naming things
+-------------
+
+Encoding the type into the function or variable name can become misleading at
+best, or dead wrong at worst. The compiler already knows what type the object
+in question is, and relaying this information to the programmer is unnecessary.
+Furthermore, overly descriptive names for variables are frowned upon, unless the
+description boosts readability.
+
+Local variables should be short and to the point. Loop counter should just be
+called ``i``. Giving temporary and single-use variables long, descriptive names
+is counterproductive and makes the code that much harder to read.
+
+Global variables should be avoided, but in cases where they *must* be used, they
+should have a name that reflects their purpose and scope. For instance:
+
+.. code-block:: c
+
+ int index_counter = 0;
+ vec3 clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
+
+Typedefs
+--------
+
+Typedefs should be avoided at the global or API level, as it can hide
+information about a struct or pointer. Things such as ``type_t`` are prone to
+create confusion and are heavily frowned upon. The rationale is that when a
+programmer sees ``type_t var``, they have no context as to how the type needs
+to be used. Instead, leave the backing type information in full view:
+
+.. code-block:: c
+
+ struct type *var;
+
+The engine has already defined the standard C23 integer types for use in
+engine code, so there is no need to do any kind of typedef. Even if the backing
+type information is platform-dependant, a simple ``void*`` is almost always
+preferable to creating a new type wholesale.
+
+Functions
+---------
+
+Functions should be short and (ideally) do one operation. They should fit on
+no more than one or two 1080p screens, and any more than that is a sign the
+function is too complex. Never be afraid to define a helper function local to
+the function's translation unit. If a function is no more than five lines long,
+it can be inlined for performance. Helper functions should be prefixed with an
+underscore and marked ``static``, so that they aren't visible by the API.
+
+The number of local variables should not exceed five or six, and any more than
+that is a good sign of an overly complex function. If you need more than that,
+the function's design should be re-thought. Psychology says that the average
+human brain can only hold between five and seven things in working memory, so
+functions should be designed accordingly. In source files, functions should be
+separated with a single blank line. In header files, any function made part of
+the API should be marked with ``RAPI`` before the function signature.
+
+In function prototypes, the function name should be included with the type
+information. This adds valuble information for the reader and makes function
+arguments easier to track in debuggers.
+
+Commenting
+----------
+
+The engine uses doxygen-style comments for generating documentation. Outside of
+this, comments should be used to explain the what and why of a piece of code.
+Avoid putting comments inside a function body unless its a TODO or FIXME tag.
+Generally, comments should be placed at the head of a function for documentation
+purposes, especially engine API functions.
+
+.. code-block:: c
+
+ /**
+ * \brief Example function
+ * \param[in] ex1 Example input
+ * \param[out] ex2 Example output
+ * \return Example return
+ */
+ int example(int ex1, int *ex2);
+
+Structs should also be commented in a similar style:
+
+.. code-block:: c
+
+ /**
+ * Example struct
+ */
+ struct example {
+ int ID; ///< Identifier
+ struct member *m; ///< Example member
+ }
+
+Member doc comments should be tabbed over so that they are in the same column.
+
+Data structures
+----------------
+
+Data structures that have visibility outside the local thread should have a
+reference count. The engine provides a reference accounting structure that is
+thread-safe and works atomically. If you think your code will be visible outside
+the current thread, don't hesitate to use it. It is better to be overly cautious
+and use more memory than to take unnecessary risks with thread-global data.
+
+In addition, reference counting means the engine can avoid locking, and allows
+multiple threads to access the data structure in parallel, or merely ensuring
+the underlying data doesn't get taken away during a lock or other operation.
+
+A good rule of thumb is that if another thread can find your structure, and it
+doesn't contain a reference count, it is almost always a bug.
+
+Macros and enums
+----------------
+
+All macros, enum values and constants should be capitalized.
+
+.. code-block:: c
+
+ #define PI 3.1415926535
+
+ enum state {
+ STATE_READY,
+ STATE_UNREADY,
+ STATE_LOCKED
+ ...
+ }
+
+ int GRAVITY = 9.8;
+
+Generally, inline functions are preferred to macros resembling functions, as
+bugs in macros are much harder to track down and don't appear in a debugger.
+Macros with multiple statements should be enclosed in a do-while block:
+
+.. code-block:: c
+
+ #define MACRO(a, b, c) \
+ do { \
+ if (a == 5) \
+ do_this(b, c); \
+ } while(0)
+
+You should avoid macros that affect control flow, depend on having a local
+variable with a magic name and macros that are used as l-values. Furthermore,
+macros that have a more complex expression should be enclosed in parentheses.
+
+.. code-block:: c
+
+ #define PI 3.14159265
+ #define AREA(x) (PI * x * x)
+
+Macros should take into account common variable names, especially those
+resembling functions. For instance:
+
+.. code-block:: c
+
+ #define FOO(x) \
+ ({ \
+ typeof(x) ret; \
+ })
+
+Conditional compilation
+-----------------------
+
+Wherever possible, the use of preprocessor conditionals should be relegated to
+header files. If you need to define a different function (say, for a different
+platform) it is best to define functions for each case and a stub for the final
+else.
+
+References
+----------
+
+* `Linux kernel coding style <https://www.kernel.org/doc/html/v4.10/process/coding-style.html>`_
diff --git a/doc/core/index.rst b/doc/core/index.rst
new file mode 100644
index 0000000..f0d8710
--- /dev/null
+++ b/doc/core/index.rst
@@ -0,0 +1,37 @@
+Core API reference
+==================
+
+Initialization
+--------------
+
+.. doxygenfile:: init.h
+
+Error handling
+--------------
+
+.. doxygenfile:: abort.h
+
+Data structures
+---------------
+
+.. doxygenfile:: list.h
+
+Logging
+-------
+
+.. doxygenfile:: logging.h
+
+Memory allocation
+-----------------
+
+.. doxygenfile:: alloc.h
+
+Mod interface
+-------------
+
+.. doxygenfile:: mod.h
+
+Multithreading
+--------------
+
+.. doxygenfile:: thread.h
diff --git a/doc/dev-process.rst b/doc/dev-process.rst
new file mode 100644
index 0000000..7484bf5
--- /dev/null
+++ b/doc/dev-process.rst
@@ -0,0 +1,43 @@
+Development process
+===================
+
+This document is intended to provide developers work with the development
+community while minimizing frustration. While there are some technical
+information here, the majority of this manual is process-oriented and does not
+require deep understanding of the engine's APIs to understand.
+
+How to contribute
+-----------------
+
+The Rune Engine is free and open source. Like any community-driven project, the
+engine relies on volunteer contributions. If you are not a programmer, no need
+to worry, as Rune requires many other roles as well. In fact, if you are a user
+of the engine and enjoy its feature set, merely putting "Made with Rune" on your
+game or application positively impacts the well-being of this project. Your
+personal success makes the engine visible to other developers, growing the
+community further.
+
+Technical contributions
+-----------------------
+
+* Report bugs and other issues - As active users of the engine, you are much
+ better equipped to track down bugs and other issues more than anyone else. To
+ let the community know about your findings, visit the
+ `Flyspray instance <https://bugs.gymli.org/index.php?do=toplevel&project=3>`_.
+* Test development versions - It is recommended to use the stable releases for
+ your projects, but you can help us test development releases, betas and
+ release candidates by running your project with them and checking what
+ problems this introduces or solves.
+* Contribute engine code - The engine development is mainly coordinated on our
+ `mailing list <https://lists.gymli.org/rune-engine/new.html>`_.
+* Review code contributions - All patches submitted to the mailing lists need to
+ be carefully reviewed before they can be merged into the mainline engine. The
+ maintainers are limited in number and how much work they can get done. You can
+ help them get a head start by participating in the code review process.
+* Demo projects - The engine has a small selection of demo projects so new users
+ can quickly test new features or get familiar with the engine in the first
+ place. Help improve existing projects or write entirely new ones to be added
+ to the pool.
+* Write documentation - The documentation is one of the most important parts of
+ the engine, and is often overlooked. If you have technical writing skills,
+ help with the engine documentation is always welcome.
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..b4dfb5a
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,46 @@
+.. Rune Game Engine documentation master file, created by
+ sphinx-quickstart on Wed Oct 16 23:36:04 2024.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Rune Game Engine documentation
+==============================
+
+Rune is a high-performance game engine written entirely in C and designed to
+support Quake-style, "boomer" shooters. It is free and open source, and has both
+2D and 3D capabilities. If you are new to this documentation, we recommend that
+you read the `introduction page <introduction.html>`_ to get an overview of features and specs that
+Rune has to offer. Please note that improvements to the documentation are
+welcome; join the rune-engine mailing list at lists.gymli.org if you want to help
+out.
+
+User-oriented documentation
+---------------------------
+
+The following manuals are written for game or application developers who are
+trying to get the engine to work for their own applications or libraries.
+
+.. toctree::
+ :maxdepth: 1
+
+ Introduction <introduction.rst>
+ List of features <feature-list.rst>
+ Core API <core/index.rst>
+ Network API <network/index.rst>
+ Rendering API <render/index.rst>
+ UI API <ui/index.rst>
+ Sound API <sound/index.rst>
+ Reporting issues <reporting-issues.rst>
+
+Working with upstream
+---------------------
+
+The guides for interacting with the engine's development community and getting
+your work upstream.
+
+.. toctree::
+ :maxdepth: 1
+
+ Development process <dev-process.rst>
+ Coding style <coding-style.rst>
+ Submitting patches <submitting-patches.rst>
diff --git a/doc/introduction.rst b/doc/introduction.rst
new file mode 100644
index 0000000..c2bba3b
--- /dev/null
+++ b/doc/introduction.rst
@@ -0,0 +1,43 @@
+Introduction
+============
+
+Welcome to the official documentation of the Rune Engine, the free and open
+source 2D and 3D game engine. This engine, being licensed under the terms of the
+very liberal zlib license, allows game and application developers to create any
+kind of game, for any platform and with no usage restriction whatsoever.
+However, as the engine's focus is on Quake-style shooters, it may be more
+difficult to create a different type of game (e.g., a top-down city builder) in
+this engine. Developers are free to make their own modifications to Rune to
+support their game and are encouraged to submit their changes to the mailing
+lists.
+
+This page gives a broad overview of the engine and this documentation, so that
+you know where to start if you are a beginner or where to look if you need more
+information about a particular feature.
+
+Before you start
+----------------
+
+Please note that much of the engine is still under heavy development, and some
+APIs have yet to be stabilized and documented. The ones listed in this
+documentation have been stabilized and nothing should be removed or changed,
+however, some functions may be added in the future should the need arise.
+
+About the Rune Engine
+---------------------
+
+A standard, "off the shelf" game engine is designed to provide a developer with
+an IDE-like interface with an editor, a publication platform, scripting engine,
+etc. Rune is designed to be just another library that a developer can use. There
+is no editor outside of the one you provide yourself. The engine is designed to
+stay out of the developer's way as much as possible, allowing the developer to
+realize their vision without distractions and fluff. Rune is built on POSIX and
+Unix principles and abstractions, so Linux and macOS developers should feel very
+at home working with Rune. The engine considers Linux a first-class citizen, so
+any code that calls engine APIs and primitives should run *unmodified* on a
+Linux system, given the application developer is only using Rune APIs.
+
+Rune is completely free and open source under the permissive zlib license. No
+strings attached and no royalities required. Users' games are theirs, down to
+the last line of engine code. Rune's development is fully community-driven,
+giving users the ability to shape the engine to meet their needs.
diff --git a/doc/submitting-patches.rst b/doc/submitting-patches.rst
new file mode 100644
index 0000000..002f7a4
--- /dev/null
+++ b/doc/submitting-patches.rst
@@ -0,0 +1,142 @@
+Submitting patches
+==================
+
+If you have experience submitting patches to the Linux kernel or similar
+projects, you are already familiar with the system Rune uses for
+community-driven development. If not, this is the guide from which you should
+begin. This manual provides a step by step guide on how to get your code into
+the engine, as well as tips on increasing the odds your changes get merged into
+the mainline release.
+
+Experience with ``git`` is expected and assumed, as the engine uses it for all
+it version control needs. If you are unfamiliar with it, the documentation for
+``git`` can be found at `this website <https://git-scm.com/doc>`_.
+
+Obtain a source tree
+----------------------------
+
+If you do not have a repository with the engine source, use ``git`` to download
+one. Most of the time, you will want a mainline repository, which can be cloned
+like so:
+
+.. code-block::
+
+ git clone git://git.gymli.org/dholman/rune-engine.git
+
+Describe your changes
+---------------------
+
+For any feature, bugfix or solution, there must have been a motivation behind
+this change. Convince the reviewer that there is a problem worth fixing or a new
+feature to be added, and make them believe its worth reading past the first few
+lines of the commit message.
+
+Optimizations and the trade-offs that were made with them should be made clear
+in the message. If you claim a performance increase, back it up with a numerical
+figure. Describe the expected downsides of your optimization so that the
+reviewer and the community at large can discuss its potential benefits and
+costs.
+
+Patches should fix only a single problem or introduce a single feature. If the
+changes you send do more than that, consider breaking them up into a series of
+patches.
+
+When a patch is submitted, the full description and justification should be
+included with it. It is on you to ensure the correct information is attached to
+the patch or patch series. Maintainers are busy guys and are not obligated to
+follow a URL to a pastebin to find the information about a patch. In other
+words, the patch (series) should be self-contained.
+
+If you need to link to a mailing list archive, prefer to use the lists.gymli.org
+service. To create the link, use the contents of the ``Message-ID`` header of
+the message without the angle brackets.
+
+.. code-block::
+
+ Link: https://lists.gymli.org/rune-engine/104
+
+Your changes should be in imperative mood and should follow the canonical patch
+format. In other words, the patch should sound as though it is ordering the code
+to change, rather than the developer merely describing his or her changes. This
+makes commit messages shorter and easier to follow. Furthermore, the message
+should be in plain English or a very close approximation as can be permitted
+when discussing technical details.
+
+If you want to refer to a specific commit or issue, don't just include the hash
+of the commit or the issue ID. The patch should contain at least a oneline
+summary of the commit or issue. This makes code review flow much more smoothly
+and allows the maintainers to know what you are referring to. The hash should at
+least include the first twelve characters of the SHA-1 hash. This reduces the
+chance of collisions even when the number of objects grows large.
+
+If a patch fixes a bug introduced in a previous commit or a bug tracker, the
+'Fixes:' tag should be used with the first twelve characters of the SHA-1 hash,
+or in the case of a public bug tracker, the 'Closes:' tag should be used with
+the relevant link.
+
+.. code-block::
+
+ Closes: https://bugs.site.tld/issues/176
+ Fixes: 123456789abc ("subsystem: file: example")
+
+Select the recipients for your patch
+------------------------------------
+
+You should always CC the appropriate maintainers and lists on any patch to code
+they maintain. A good bet is to send it to the email attached to the
+``git blame`` data and the main discussion list. If you cannot contact the
+relevant maintainer for the subsystem you are working on, Danny Holman, being
+the final arbiter of all changes accepted into the engine, serves as maintainer
+of last resort.
+
+Formatting
+----------
+
+Danny and other engine developers need to be able to read and comment on the
+changes you are submitting. If a maintainer cannot quote your changes using
+standard, plain text tools, it is almost guaranteed to be ignored. For this
+reason, all patches should be submitted by email "inline". By far, the easiest
+way to do this is to use ``git send-email``. The documentation linked in the
+opening paragraphs has a section dedicated to this tool.
+
+Furthermore, all patches should contain 'PATCH' in the subject line. This makes
+actual patches distinguishable from other email discussions. The
+``git send-mail`` tool will do this automatically.
+
+Sign your work
+--------------
+
+To facilitate copyright and to keep track of who submitted changes, all patches
+should include a sign-off at the end of the commit message. This certifies you
+wrote the patch or otherwise have the right to pass it on as open source. See
+the ``dco.txt`` file for the exact requirements.
+
+When committing, ``git`` will do this automatically when you specify
+``--signoff`` as part of the command flags. Alternatively, you can define an
+alias in your ``.gitconfig`` file that will shorten ``git commit --signoff`` to
+something similar to ``git cs``.
+
+Canonical patch format
+----------------------
+
+The canonical patch subject line is:
+
+.. code-block::
+
+ Subject: [PATCH 1/X] subsystem: summary phrase
+
+The body contains the following:
+
+* A ``from`` line specifying the patch author, followed by an empty line
+* The body of the explanation, line wrapped at 75 columns, which will be copied
+ to the permanent changelog to describe this patch
+* An empty line
+* The ``Signed-off-by:`` lines, described above
+* A marker line containing simply ``---``
+* Any additional comments not suitable for the changelog
+* The actual patch (``diff`` output)
+
+References
+----------
+
+* `Linux kernel patch submission guide <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`_