32 lines
No EOL
8.3 KiB
Markdown
32 lines
No EOL
8.3 KiB
Markdown
# Licar
|
|
|
|
Licar (short for *[libre](libre.md) car*), also known as *the best racing game ever made*, is a fully [public domain](public_domain.md), [free software](free_software.md) and [free culture](free_culture.md) 3D racing [game](game.md) by [drummyfish](drummyfish.md), highly inspired by the proprietary game [Trackmania](trackmania.md). Licar is made in similar fashion to [Anarch](anarch.md) (another drummyfish's game) but is a little more [bloated](bloat.md): it is a fully [3D game](3d_rendering.md) made with [small3dlib](small3dlib.md) and [tinyphysicsengine](tinyphysicsengine.md) and although it's not the most [minimalist](minimalism.md) game under the Sun, it is still very much [KISS](kiss.md), extremely [portable](portability.md), not using any third party [libraries](library.md) etc. The [git](git.md) repo is currently at http://git.coom.tech/drummyfish/Licar; version 1.0 of the game was released on 25.06.2025 after 329 commits. The creation of Licar was conducted purely with free software ([GIMP](gimp.md), [Blender](blender.md), [GNU](gnu.md)/[Linux](linux.md), [vim](vim.md), ...) and relatively old computers (mainly Thinkpad X200).
|
|
|
|
The game's features include a fully 3D, completely [deterministic](determinism.md) physics, lovely soulful [software rendering](sw_rendering.md), replays, ghost cars and custom maps (written in a plain [ASCII](ascii.md) text format). In the base package there are 5 standard, 5 tiny and 2 bonus maps.
|
|
|
|
Drummyfish made Licar to fulfill one of his long held dreams of making a Trackmania [clone](clone.md), for he used to love the game but had to abandon it once he started abstaining from [proprietary](proprietary.md) software. The [project](project.md) also offered an opportunity to showcase drummyfish's major libraries and to demonstrate some of the [LRS](lrs.md) principles on a bigger project -- although the game isn't truly an LRS ideal, it still shows how powerful minimalism can be, even when applied to a relatively mainstream vision of what a video game is. By this it can potentially and hopefully reach more [normies](npc.md).
|
|
|
|
Just like Anarch, Licar adheres to basic LRS [programming](programming.md) practices, for example it is fully written in [C99](c.md), is completely public domain under [CC0](CC0.md), uses no build system, no third party libraries, doesn't rely on standard library, doesn't use [floating point](float.md) and embeds its configuration and assets right in the source code (except for optional [music](music.md) and external data file). The whole game was made completely from scratch, including all assets, the text font, recording own musical samples for custom sound font for the soundtrack etc. The whole code has around 25 thousand [lines of code](loc.md). Needless to say the game is very portable end efficient as a result: the compiled binary (including embedded assets) usually weights around 300 kB, the program runs with less than 500 kB [RAM](ram.md) on [CPUs](cpu.md) clocking even around 100 MHz. It was even run on [Pokitto](pokitto.md), albeit in an extremely limited way.
|
|
|
|
## Technical Detail
|
|
|
|
Licar is wholly written in [C99](c99.md) and only uses [small3dlib](small3dlib.md) (S3L) and [tinyphysicsengine](tincyphysicsengine.md) (TPE) as libraries -- apart from these no other libraries are used (not even standard library, except for using fixed size integers from *stdint.h*). The code is a single compilation unit, i.e. everything is implemented as header files (including S3L and TPE) that are included by a frontend which is then the only file to compile (no need for manual linking, build systems and whatnot). Of course specific frontends have to use some kind of [I/O](io.md) library to deliver interaction with the player, but these are not hard [dependencies](dependency.md) of the game itself, only of a specific frontend -- several frontends are implemented, including [SDL2](sdl.md), [CSFML](csfml.md) and [X11](x11.md). Frontends are very simple as they're only required to implement extremely basic functions such as a pixel drawing function, key press checking function and a few others. The game was successfully compiled and played under [GNU](gnu.md)/[Linux](linux.md), [Win$hit](windows.md), [OpenBSD](openbsd.md), on [Raspberry Pi](rpi.md), in [web](www.md) browser and even on very weak devices such as [Pokitto](pokitto.md) and [ESPBoy](espboy.md), albeit in a very limited "tech demo" way. When counting raw lines (`wc -l`), all code (including frontends etc.) totals around 25000 [lines of code](loc.md), whilst only the pure game code (only header files) has around 21000 lines.
|
|
|
|
No [floating point](float.md) is ever used in the source code, everything (including 3D rendering and 3D physics) is implemented with 32 bit [fixed point](fixed_point.md).
|
|
|
|
**Graphics**: like with Anarch, rendering to actual screen is realized through a frontend-defined pixel drawing [function](function.md) that's used by the game code to render everything from [GUI](gui.md) and text to the 3D view. [RGB565](rgb565.md) (65536 colors) is used as a color format, with the option to turn on [RGB332](rgb332.md) (256 colors) as well. All images are embedded in the source code and stored in 64x64 resolution in indexed format (except for sky images which are effectively composed of 2x2 normal images to give a higher resolution). The car [3D model](3d_model.md) is also embedded in source code. The models of map blocks are created in code. When loading a map, its 3D model is created and invisible triangles are [culled](culling.md) away (which is a little time consuming and makes bigger maps take longer to load). The map model triangles are then sorted so that the map is split into 64 (4x4x4) chunks -- only nearest 8 chunks of the map are being rendered at any time. Far away chunks are cheaply drawn as a very primitive "[LOD](lod.md)", simply a flat-colored 2D half-transparent square. All transparency is handled by [dithering](dithering.md). Text is drawn using a custom simple, [vector](vector.md), "segmented-display-like" font whose data are embedded in the source code.
|
|
|
|
**Physics**: physics is [deterministic](determinism.md) and is always calculated at 30 ticks per second, no matter what the rendering FPS is, [interpolation](interpolation.md) is additionally applied to smooth the animation for rendering. Internally the car is composed of 5 spheres (4 wheels and the body) and is technically a soft body, but the shape is iteratively "stiffened" so that it appears as a rigid body. The relative position of the spheres is used to determine the car's orientation which is then applied to the 3D model for rendering. The map's shape in the physics world is modeled by a sort of [signed distance function](sdf.md) to handle [collisions](collision.md) with the car.
|
|
|
|
**Audio**: all audio is in very simple 8 bit 8 KHz mono format. Sound effects are all generated [procedurally](procgen.md). The game comes with a manually created background music track stored in raw format in a separate file, which can be played by the frontend if it can and wants to.
|
|
|
|
And finally some more uncategorized details. Maps are created in a plain text mini-language that specified where to place individual map blocks, what material and transformation they have etc. The process of loading a map includes reading this format and transforming it into the internal binary representation in which blocks are [sorted](sorting.md) so that looking up blocks can be done very quickly with binary search (this is crucial for resolving collisions as we need to quickly check the car's nearest blocks for collisions). Replays are similarly stored in a plain text format -- each replay record takes 16 bits and stores a change in input along with ticks since the last record (if the bits don't suffice to encode the ticks, a redundant no-change record is simply inserted). All these text data (i.e. mainly maps and replays) are stored in a virtual *data file* -- behind the scenes this files consists of the *internal data file* (one containing the basic maps, compiled right in the binary) and an optional *external data file*, which on platforms with filesystems is a normal file that can be edited to add more maps etc. Almost everything in the game is optional and can be turned off so that it's possible to play it on any kind of potato -- there can be no sound, texturing, no file system, no color display etc.
|
|
|
|
## Postmortem
|
|
|
|
TODO: some reflections n shit here
|
|
|
|
## See Also
|
|
|
|
- [Anarch](anarch.md)
|
|
- [LRS](lrs.md) |