# T1. About Townengine{twn}

Go back

T1.1 Introduction

> Townengine, {twn}, is an opinionated game development framework designed around specific set of ideas:

> Simplicity. It makes assumptions that trickle down to your game code. There's no delta between frames, nor resolution change. Textures have constant known size, not requiring scaling.

> Managed state. Designed around this we can provide hot reloading at any point, serialization for save files and debug dumps, as well as synchronization over network, without any user code. Every frame apparent engine state is cleared, which removes another variable for you to handle, - when to initialize. There's no need for you to call `LoadImage()` of sorts before using it in render, you just pass filepaths around. Input is initialized anew each frame, making rebinds trivial.

> Device care. Older hardware is still used in many parts of the world, which users might not otherwise be able to make games they dream of. Restrictions also constitute in desired aesthetics. Graphics capabilities are limited, but what is present, - is heavily optimized. It is rather different from performance-driven approach that tries to take advantage of the latest hardware and features, sacrificing both the reach and portability in process.

> Portability. Written in C11 with all dependencies being in C, it's possible to compile it to most platforms. SDL2 is at the center and you cannot get better than this. Default graphics API is OpenGL 1.5 with extension detection. As an example, it builds and runs on Haiku OS with LLVMpipe.

> Language agnosticism. API is restricted to minimize the amount of glue code. Language interpreters don't need to be part of the engine itself. Anything with C ABI support can link to it. /share/twn_api.json schema is provided for automatic binding and annotation generation.

> Use-case orientation. It doesn't try to be a yet another general purpose engine conquering all and nothing. Instead we seek particular use cases and implement the most essential parts. User code copying should be promoted instead of delegating it all to the engine, this way we don't restrict.

> Iterability. Defaults provided for most of the API, making initial code faster to spring. Hot reloading works for both assets and code.

> Low latency. Care is given to various incarnations of feared latency. Engine is fast to build, allowing for low commitment local patches. Startup time is profiled and frequently looked into. Streaming is used as much as possible.

> No-Versioning. We don't stick to releases and "contract" obligations for things to remain stagnant. It's fair to ask end user to put little effort if they need newer set of features, instead of putting all the burden on us. You can always just stick to particular version you started the development of the project with, {twn} doesn't need system wide installation.

> Bounded. Most places assume runtime limits, to help with portability and growing out-of-hand complexity. Frames cannot take more than sane allocated time, breaking off infinite loops.

> Toolable. External editors are the way, with their own separate modes of being. Simple web socket interface will be defined for that.

T1.2 Wiki

> Purpose of this wiki is to collect information on various usages of {twn} across the genres, FAQ style. You're welcomed to contribute to it. It's written in HTML so basic you can edit it by hand. Just check template.html.

> Content is divided into chapters, where prefix specifies its category. Currently following prefixes are used:

> - T for townengine; development and apis.
> - G for gamedev; guides and FAQs on game making.

> There's no reason not to pile up knowledge, refactoring is irrelevant.

T1.3 Procedure Interface

> For native code ABI defines convention to ease tooling integration. Platform/compiler C ABI is assumed, but it should be trivially expressible in JSON-RPC as well.

> - 32 bit floating point is the only numeric type.
> - Procedure parameters can only use basic types, with no aggregates. Exceptions are Vec, Rect and Color types. (see /include/twn_types.h)
> - Enum types are allowed, but must be converted to floats. Identity strings are preferred.
> - No opaque nor pointer types allowed, use string keys if needed. Think of it as data base relations.
> - Only null terminated string is allowed as a sequential type in both parameters and returns.
> - Return value could be a simple aggregate that is translatable to a dictionary of primitives, without nesting.
> - Symbols should not contain numerics. For example, sqrt2 must become square_root.
> - /share/twn_api.json file is hand-kept with a schema to aid automatic binding generation and tooling.
> - Parameter names should not collide with keywords of any language that is targeted; if so happens, parameter alias could be added. Currently forbidden: repeat.
> - Procedure can't have more than 8 parameters.
> - Decimal portions of floating points are lossy both due to rounding errors and text representation, thus they cannot be relied to hold for equality. Integer parts of floats are good up to 2^24.
> - Returns must be restricted/closed on being constant over frame, parameters or asset frame.

T1.4 Developing

> One of hard choices we employ is requirement on having more or less the same tools on all platforms in order to compile. If you're on Windows you need to get a MinGW environment. [cmake] and [python3] (>specify versions<) are also required. [clang] is preferred over [gcc], as it has superior lto, which matters a great deal with our architecture (literal day and night difference in frame time). [git] is used for version control. Git for Windows distribution could also be used for getting conforming cli environment, much recommended.

> Inside $TWNROOT/bin folder the [twn] script is used for engine instrumentation. It could build and run your projects and even open this very wiki locally! You could execute [source hooks] inside $TWNROOT to add [twn] to your $PATH temporarily. Symlinking of it is also supported. Look inside the script to see what it can do, it's ever growing !

> [twn init <template> <name>] could be used to quickly initialize a project. Look into $TWNROOT/apps/templates folder to see available templates.

> Support for [clangd] completions is provided with [twn devcompl] command, it generates compile_commands.json inside $TWNROOT/build folder. Having workspace placed in $TWNROOT by your IDE should be enough to make it all work. Rerun [twn devcompl] if new files are added.

> Web target requires [emsdk] as of now. Use [twn build --target=web] to use it.