--- /dev/null
+* text=auto
--- /dev/null
+# Build directory
+bin/
+obj/
+tags
+
+ Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+vgcore.*
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+
+compile_commands.json
+.cache/
+.clang_complete
+# .clangd
+.session
+
+lrts
+testlrts
+*.patch
--- /dev/null
+# Known Bugs
+
+
--- /dev/null
+Copyright 2025-2026 Lukas Krickl (lukas@krickl.dev)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction,
+including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS",
+WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+# lrts
+
+lukas' real time strategy.
+
+## Table of content
+
+- [Installation](#Installation)
+- [Usage](#Usage)
+- [License](#License)
+- [Contributing](#Contributing)
+- [TODO](#TODO)
+
+## Installation
+
+To build this program you will require a recent C compiler, and make.
+
+```sh
+make # to compile all targets
+```
+
+## Usage
+
+Usage instructions can be found in the manual.
+
+- man/lrts.1: Command reference
+
+## License
+
+This program is distributed under the terms of the MIT License.
+
+## Contributing
+
--- /dev/null
+# Coding Style
+
+## Modules
+
+The code base is split into modules.
+Files and all functions therein are prefixed with one of the following:
+
+- `lrts_`: public api
+- `t_`: thinker related
+- `r_`: rendering
+- `n_`: network
+- `m_`: macro command language
+- `c_`: client-side code
+- `s_`: server side code
+- `u_`: system utility code
+- `p_`: platform module directory
+
+
+## Library functions
+
+Third party functions (even the C stdlib) should be wrapped at all times.
+Platform specific code (including the stdlib) should be clearly marked.
+
+## Platforms
+
+Similar to modules platforms contain a concrete implemntation for specific modules.
+Platforms are contained in specific directories which start with `p_`.
+Usually platforms contain no additional header files.
+
+Currently supported platforms are:
+
+- p_pc: generic PC implementation of functionality using the C stdlib
+- p_posix: posix specific code
+- p_win: win32 specific code
+- p_r_cli: cli-based renderer
+- p_r_sdl: sdl-based renderer
+
+It is possible to enable more than one platform at a time e.g. usually p_pc, p_posix and one renderer are
+enabled to allow the program to compile.
--- /dev/null
+NAME=lrts
+TEST_NAME=test$(NAME)
+DBGCFLAGS=-g -fsanitize=address
+DBGLDFLAGS=-fsanitize=address
+CFLAGS=-Wall -pedantic $(DBGCFLAGS) -std=c89
+LIBS=
+LDFLAGS=$(DBGLDFLAGS) $(LIBS)
+
+INSTALL_DIR=/usr/local
+OBJS:=
+
+CCOBJ=$(CC) -c -o $@ $< $(CFLAGS) $(LDFLAGS)
+
+all: bin test
+
+release:
+ make DBGCFLAGS="" DBGLDFLAGS=""
+
+.PHONY: FORCE
+FORCE:
+
+main.o: src/main.c FORCE
+ $(CCOBJ)
+test.o: src/test.c FORCE
+ $(CCOBJ)
+
+
+bin: main.o $(OBJS)
+ $(CC) -o $(NAME) main.o $(OBJS) $(CFLAGS) $(LDFLAGS)
+
+test: test.o $(OBJS)
+ $(CC) -o $(TEST_NAME) test.o $(OBJS) $(CFLAGS) $(LDFLAGS)
+
+.PHONY: clean
+clean:
+ rm -f ./*.o
+ rm -f ./$(NAME)
+ rm -f ./$(TEST_NAME)
+
+.PHONY: install
+install:
+ mkdir -p $(INSTALL_DIR)/bin
+ mkdir -p $(INSTALL_DIR)/man/man1
+ mkdir -p $(INSTALL_DIR)/man/man5
+ cp ./$(NAME) $(INSTALL_DIR)/bin
+ cp ./man/$(NAME).1 $(INSTALL_DIR)/man/man1
+ cp ./man/$(NAME).5 $(INSTALL_DIR)/man/man5
+
--- /dev/null
+.\" Manpage for lrts.
+.\" Contact lukas@krickl.dev to correct errors or typos.
+
+.TH man 1 "21 Febuary 2026" "0.0.1" "lrts manual"
+
+.SH NAME
+ lrts
+.SH SYNOPSIS
+ lrts [-hvV] [-c=command]
+.SH DESCRIPTION
+ lrts
+
+ -h
+ display this help and exit
+
+ -V
+ display version info and exit
+
+ -v
+ verbose output
+
+ -c
+ execute a command and exit
+
+.SH EXAMPLES
+
+.SH SEE ALSO
+ lrts(5) for a command syntax reference
+
+ The documentation for make(1) for compilation instructions.
+
+ A compiler documentation such as cc(1) gcc(1) or clang(1).
+
+.SH BUGS
+
+.SH AUTHOR
+ Lukas Krickl (lukas@krickl.dev)
+
+.SH COPYRIGHT
+ Copyright 2026 Lukas Krickl (lukas@krickl.dev)
--- /dev/null
+.\" Manpage for lrts.
+.\" Contact lukas@krickl.dev to correct errors or typos.
+
+.TH man 5 "21 Febuary 2026" "0.0.1" "lrts command language reference"
+
+.SH SEE ALSO
+
+ lrts(1) for a reference on how to use lrts.
+
+.SH AUTHOR
+ Lukas Krickl (lukas@krickl.dev)
+
+.SH COPYRIGHT
+ Copyright 2026 Lukas Krickl (lukas@krickl.dev)
--- /dev/null
+#ifndef CONFIG_H__
+#define CONFIG_H__
+
+/*
+ * This is the global config file for the project
+ */
+
+#define LRTS_VER "0.0.1"
+
+#define LRTS_DEBUG
+
+/* Platform and renderer configuration */
+#define LRTS_PLATFORM_POSIX
+#define LRTS_RENDERER_CLI
+
+#endif
--- /dev/null
+#include <string.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include "u_stdio.h"
+#include "u_defs.h"
+#include "p_platform.h"
+
+struct lrts_config lrts_global_cfg;
+
+struct lrts_config* lrts_cfg() {
+ return &lrts_global_cfg;
+}
+
+void lrts_help(int argc, char **argv) {
+ u_fprintf(u_stderr, "%s\n", argv[0]);
+ u_fprintf(u_stderr, "Usage: %s [-%s] [-c=command]\n\n",
+ argv[0], LRTS_OPTS);
+ LRTS_HELP("h", "display this help and exit");
+ LRTS_HELP("V", "display version info and exit");
+ LRTS_HELP("v", "verbose output");
+}
+
+void lrts_version(void) {
+ u_fprintf(u_stderr, "%s\n", LRTS_VER);
+}
+
+void lrts_getopt(int argc, char **argv, struct lrts_config *cfg) {
+ int c = 0;
+ while ((c = getopt(argc, argv, LRTS_OPTS LRTS_OPTS_ARG)) != -1) {
+ switch (c) {
+ case 'h':
+ lrts_help(argc, argv);
+ exit(0);
+ break;
+ case 'V':
+ lrts_version();
+ exit(0);
+ break;
+ case 'v':
+ cfg->verbose = 1;
+ break;
+ case '?':
+ break;
+ default:
+ u_fprintf(u_stderr, "%s: invalid option '%c'\nTry '%s -h' for more information.\n",
+ argv[0], c, argv[0]);
+ exit(-1);
+ break;
+ }
+ }
+
+ cfg->argc = argc - optind;
+ cfg->argv = argv + optind;
+}
+
+int lrts_main(int argc, char **argv) {
+ p_io_init();
+ lrts_getopt(argc, argv, lrts_cfg());
+
+ p_render_init();
+
+ p_renderer_finish();
+ p_io_finish();
+
+ return 0;
+}
--- /dev/null
+#ifndef LRTS_H__
+#define LRTS_H__
+
+
+/**
+ * System includes
+ */
+#include "u_assert.h"
+#include "u_defs.h"
+#include "config.h"
+
+
+
+/**
+ * If this is an implementation
+ * we include all c files for a mono-build
+ */
+#ifdef LRTS_IMPL
+
+#include "lrts.c"
+
+/** platform specific includes **/
+#ifdef LRTS_PLATFORM_POSIX
+#include "p_pc/u_stdio.c"
+#include "p_pc/u_mem.c"
+#include "p_pc/u_assert.c"
+#include "p_posix/p_init.c"
+#else
+#error "No platform is provided"
+#endif
+
+#ifdef LRTS_RENDERER_CLI
+#include "p_r_cli/p_init.c"
+#else
+#error "No renderer is provided"
+#endif
+
+
+#include "t_actor.c"
+#include "u_rand.c"
+#include "n_conn.c"
+
+#endif
+
+#endif
--- /dev/null
+#define LRTS_IMPL
+
+#include "lrts.h"
+
+int main(int argc, char **argv) {
+ return lrts_main(argc, argv);
+}
--- /dev/null
+#include "n_conn.h"
--- /dev/null
+#ifndef N_CONN_H__
+#define N_CONN_H__
+
+#endif
--- /dev/null
+#include <assert.h>
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+#include "../u_mem.h"
+
+
+void *u_memset(void *src, int c, size_t n) {
+ return memset(src, c, n);
+}
+
+void *u_memcpy(void *dst, const void *src, size_t n) {
+ return memcpy(dst, src, n);
+}
+
+void *u_malloc(size_t size) {
+ return malloc(size);
+}
+
+void u_free(void *ptr) {
+ free(ptr);
+}
+
+void *u_realloc(void *ptr, size_t size) {
+ return realloc(ptr, size);
+}
--- /dev/null
+#include <stdarg.h>
+#include <stdio.h>
+#include "../u_stdio.h"
+
+void *u_stdin;
+void *u_stdout;
+void *u_stderr;
+
+int u_fprintf(U_FILE* stream, const char *fmt, ...) {
+ int res = 0;
+ va_list args;
+
+ va_start(args, fmt);
+ res = vfprintf(stream, fmt, args);
+ va_end(args);
+
+ return res;
+}
+
--- /dev/null
+#ifndef P_PLATFORM_H__
+#define P_PLATFORM_H__
+
+/**
+ * This module contains init code for platforms
+ */
+
+/*
+ * Init call for IO routines.
+ * This should set up stdin, stdout and stderr
+ */
+int p_io_init(void);
+
+/**
+ * Ends the io platform.
+ * Should close all open files.
+ */
+int p_io_finish(void);
+
+/**
+ * Sets up the renderer
+ */
+int p_render_init(void);
+
+/**
+ * Quits rendering
+ */
+int p_renderer_finish(void);
+
+#endif
--- /dev/null
+#include "../p_platform.h"
+#include "../u_stdio.h"
+
+int p_io_init(void) {
+ u_stdin = stdin;
+ u_stdout = stdout;
+ u_stderr = stderr;
+
+ return 0;
+}
+
+int p_io_finish(void) {
+ return 0;
+}
--- /dev/null
+#include "../p_platform.h"
+
+int p_render_init(void) {
+ return 0;
+}
+
+int p_renderer_finish(void) {
+ return 0;
+}
--- /dev/null
+#include "t_actor.h"
--- /dev/null
+#ifndef T_ACTOR_H__
+#define T_ACTOR_H__
+
+enum t_actor_flags {
+ T_ACTOR_F_NONE = 0
+};
+
+/**
+ * Character stats
+ */
+struct t_stats {
+ /**
+ * base stats
+ */
+ short str;
+ short wis;
+ short agi;
+ short vit;
+
+ /* resistances */
+ short poison_res;
+ short fire_res;
+ short holy_res;
+ short chaos_res;
+
+ /* damage stats */
+ unsigned int physical_damage;
+ unsigned int magic_damage;
+
+ /* misc */
+ unsigned char tohit;
+};
+
+/* current actor state
+ * this struct mostly contains
+ * mutable variables related to an actor
+ */
+struct t_actor_state {
+ int hp;
+ int mp;
+ int level;
+ int xp;
+};
+
+enum t_actor_type {
+ T_ACTOR_TYPE_PLAYER,
+ T_ACTOR_TYPE_PET
+};
+
+struct t_actor {
+ unsigned int id;
+ enum t_actor_type type;
+
+ unsigned short faction_id;
+
+ struct t_stats stats;
+ struct t_actor_state state;
+};
+
+
+#endif
--- /dev/null
+#define LRTS_IMPL
+
+#include <stdio.h>
+#include <assert.h>
+#include "lrts.h"
+#include "p_platform.h"
+
+#define TESTBEGIN(name) { u_fprintf(u_stderr, "%s\n", name); }
+
+#define TESTEND(name) { u_fprintf(u_stderr, "%s\n", name); }
+
+int main(int argc, char **argv) {
+ p_io_init();
+
+ TESTBEGIN("lrts test");
+ lrts_getopt(argc, argv, lrts_cfg());
+
+ TESTEND("lrts test");
+
+ p_io_finish();
+ return 0;
+}
--- /dev/null
+#ifndef U_ASSERT_H__
+#define U_ASSERT_H__
+
+#ifdef DEBUG
+
+#define lrts_assert(e, message) assert(e)
+
+#define lrts_todo(message) assert(0)
+
+#else
+
+#define lrts_assert(e, message)
+
+#define lrts_todo(message)
+
+#endif
+
+#endif
--- /dev/null
+#ifndef U_DEFS_H__
+#define U_DEFS_H__
+
+/**
+ * This module contains global type defs and constants
+ *
+ */
+
+
+/* args without value */
+#define LRTS_OPTS "hvV"
+
+/* args with value */
+#define LRTS_OPTS_ARG "c:"
+#define LRTS_HELP(a, desc) u_fprintf(u_stderr, "\t-%s\t%s\n", (a), desc);
+
+/**
+ * generic typedefs
+ */
+
+typedef unsigned char lrts_bool;
+#define LRTS_TRUE 1
+#define LRTS_FALSE 0
+
+struct lrts_config {
+ lrts_bool verbose;
+
+ char **argv;
+ int argc;
+};
+
+typedef unsigned char u8;
+typedef char i8;
+typedef unsigned short u16;
+typedef short i16;
+typedef unsigned int u32;
+typedef int i32;
+
+struct lrts_config* lrts_cfg();
+void lrts_help(int argc, char **argv);
+void lrts_version(void);
+void lrts_getopt(int argc, char **argv, struct lrts_config *cfg);
+int lrts_main(int argc, char **argv);
+
+#endif
--- /dev/null
+#ifndef U_MEM_H__
+#define U_MEM_H__
+
+
+void *u_memset(void *src, int count, size_t n);
+void *u_memcpy(void *det, const void *src, size_t n);
+
+void *u_malloc(size_t size);
+void u_free(void *ptr);
+void *u_realloc(void *ptr, size_t size);
+
+#endif
--- /dev/null
+#include "u_rand.h"
+#include "u_assert.h"
+
+void u_srand(u32 s) {
+ lrts_todo("Not yet implemented");
+}
+
+u32 u_rand(void) {
+ lrts_todo("Not yet implemented");
+ return 0;
+}
--- /dev/null
+#ifndef U_RAND_H__
+#define U_RAND_H__
+
+#include "u_defs.h"
+
+void u_srand(u32 s);
+
+u32 u_rand(void);
+
+#endif
--- /dev/null
+#ifndef U_STDIO_H__
+#define U_STDIO_H__
+
+
+#define U_FILE void
+
+extern void *u_stdin;
+extern void *u_stdout;
+extern void *u_stderr;
+
+int u_fprintf(U_FILE* stream, const char *fmt, ...);
+
+
+#endif