diff --git a/README.md b/README.md index 7304c60b..93038324 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,15 @@ - **[Adventure games & Visual novels](games/adventure/_toc.md)** (14) - **[Game frameworks](games/framework/_toc.md)** (46) - **[Popular required libraries](games/library/_toc.md)** (23) -- **[Role Playing Games](games/rpg/_toc.md)** (44) +- **[Role Playing Games](games/rpg/_toc.md)** (46) - **[Simulation games](games/simulation/_toc.md)** (10) -- **[Strategy games](games/strategy/_toc.md)** (37) +- **[Strategy games](games/strategy/_toc.md)** (41) [comment]: # (end of autogenerated content) A collection of open source games sorted by genre. The projects are at least in beta stage with a code basis that builds into an executable demo. Related infos and tips geared toward building the games are collected here. Emphasis is on support for Windows, Linux and Android. -Motivation: I want to improve the process of building open source games, maybe even rescuing some lost projects. -I concentrate on the hardware/software platforms that I have access to. - See also the list of [popular games on Github](https://github.com/leereilly/games) by Lee Reilly. ## Contributing @@ -38,6 +35,9 @@ and further actions I intend to do. - Simplifying dependencies - Increasing the number of supported platforms +I want to improve the process of building open source games, maybe even rescuing some lost projects. +I concentrate on the hardware/software platforms that I have access to. + ## Disclaimer No warranty whatsoever of the information presented herein for any purpose. There could be errors in here. diff --git a/games/framework/blender_game_engine.md b/games/framework/blender_game_engine.md index 323993d5..1b860073 100644 --- a/games/framework/blender_game_engine.md +++ b/games/framework/blender_game_engine.md @@ -5,7 +5,7 @@ _Included in Blender is a complete game engine, allowing you to create a fully f - Home: https://www.blender.org/features/game-creation/ - Download: https://www.blender.org/download/ - State: mature -- Code: http://git.blender.org/blender.git +- Code: https://developer.blender.org/diffusion/ - Language(s): C++ - License: GPL-2.0 diff --git a/games/framework/dash.md b/games/framework/dash.md index 6e9a2e48..64e4401b 100644 --- a/games/framework/dash.md +++ b/games/framework/dash.md @@ -2,8 +2,7 @@ _OpenGL engine written in the D language._ -- Home: http://circularstudios.com/#dash -- Download: http://dash.circularstudios.com/guides/gettingstarted.html +- Home: https://dash.circularstudios.com/ - Code: https://github.com/Circular-Studios/Dash - Language(s): D - License: MIT diff --git a/games/maintenance.py b/games/maintenance.py index f1d11bd8..a1aa19cb 100644 --- a/games/maintenance.py +++ b/games/maintenance.py @@ -2,7 +2,8 @@ Counts the number of records each subfolder and updates the overview. Sorts the entries in the contents files of each subfolder alphabetically. - TODO check for external dead links (if desired, only now and then) + This script runs with Python 3, it could also with Python 2 with some minor tweaks probably, but that's not important. + TODO remove "?source=navbar" from the end of links (sourceforge specific) TODO check for "_{One line description}_" or "- Wikipedia: {URL}" in game files and print warning TODO print all games without license or code information @@ -11,22 +12,40 @@ TODO in readme put contents to the top, put all games folder into another folder and this script as well as the template too TODO change Wikipedia to Media TODO single player to SP, multi player to MP for keywords - TODO list those with exotic licenses (not GPL, zlib, MIT, BSD) + TODO list those with exotic licenses (not GPL, zlib, MIT, BSD) or without licenses TODO Which C, C++ projects do not use CMake TODO list those inactive (sort by year backwards) """ import os import re +import urllib.request +import http.client + +def get_category_paths(): + """ + Returns all sub folders of the games path. + """ + return [os.path.join(games_path, x) for x in os.listdir(games_path) if os.path.isdir(os.path.join(games_path, x))] + +def get_entry_paths(category_path): + """ + Returns all files of a category path, except for '_toc.md'. + """ + return [os.path.join(category_path, x) for x in os.listdir(category_path) if x != '_toc.md' and os.path.isfile(os.path.join(category_path, x))] def read_first_line_from_file(file): + """ + Convenience function because we only need the first line of a category overview really. + """ with open(file, 'r') as f: line = f.readline() return line def read_interesting_info_from_file(file): """ - Parses a file for some interesting fields and concatenates the content + Parses a file for some interesting fields and concatenates the content. To be displayed after the game name in the + category overview. """ with open(file, 'r') as f: text = f.read() @@ -60,7 +79,7 @@ def read_interesting_info_from_file(file): def update_readme(): """ - Recounts entries in subcategories and writes them to the readme + Recounts entries in subcategories and writes them to the readme. Needs to be performed regularly. """ print('update readme file') @@ -78,19 +97,19 @@ def update_readme(): end = matches[2] # get sub folders - subfolders = [x for x in os.listdir(games_path) if x != '.git' and os.path.isdir(os.path.join(games_path, x))] + category_paths = get_category_paths() # get number of files (minus 1) in each sub folder - n = [len(os.listdir(os.path.join(games_path, folder))) - 1 for folder in subfolders] + n = [len(os.listdir(path)) - 1 for path in category_paths] # assemble paths - paths = [os.path.join(games_path, folder, '_toc.md') for folder in subfolders] + paths = [os.path.join(path, '_toc.md') for path in category_paths] # get titles (discarding first two ("# ") and last ("\n") characters) titles = [read_first_line_from_file(path)[2:-1] for path in paths] - # combine folder name, number, titles in one list - info = zip(titles, subfolders, n) + # combine titles, category names, numbers in one list + info = zip(titles, [os.path.basename(path) for path in category_paths], n) # sort according to title info = sorted(info, key=lambda x:x[0]) @@ -108,32 +127,30 @@ def update_readme(): def update_category_tocs(): """ - Lists all entries in all sub folders and generates the list in the toc file + Lists all entries in all sub folders and generates the list in the toc file. Needs to be performed regularly. """ - # get sub folders - subfolders = [x for x in os.listdir(games_path) if x != '.git' and os.path.isdir(os.path.join(games_path, x))] + # get category paths + category_paths = get_category_paths() - # for each subfolder - for folder in subfolders: - print('generate toc for {}'.format(folder)) + # for each category + for category_path in category_paths: + print('generate toc for {}'.format(os.path.basename(category_path))) # read toc header line - toc_folder = os.path.join(games_path, folder) - toc_file = os.path.join(toc_folder, '_toc.md') + toc_file = os.path.join(category_path, '_toc.md') toc_header = read_first_line_from_file(toc_file) - # get all files - files = [x for x in os.listdir(toc_folder) if x != '_toc.md' and os.path.isfile(os.path.join(toc_folder, x))] - paths = [os.path.join(toc_folder, file) for file in files] + # get paths of all entries in this category + entry_paths = get_entry_paths(category_path) # get titles (discarding first two ("# ") and last ("\n") characters) - titles = [read_first_line_from_file(path)[2:-1] for path in paths] + titles = [read_first_line_from_file(path)[2:-1] for path in entry_paths] # get more interesting info - more = [read_interesting_info_from_file(path) for path in paths] + more = [read_interesting_info_from_file(path) for path in entry_paths] # combine name and file name - info = zip(titles, files, more) + info = zip(titles, [os.path.basename(path) for path in entry_paths], more) # sort according to title info = sorted(info, key=lambda x:x[0]) @@ -149,6 +166,61 @@ def update_category_tocs(): with open(toc_file, 'w') as f: f.write(text) +def check_validity_external_links(): + """ + Checks all external links it can find for validity. Prints those with non OK HTTP responses. Does only need to be run + from time to time. + """ + # regex for finding urls (can be in <> or in () or a whitespace + regex = re.compile(r"[\s\n]<(http.+?)>|\]\((http.+?)\)|[\s\n](http[^\s\n]+)") + + # count + number_checked_links = 0 + + # get category paths + category_paths = get_category_paths() + + # for each category + for category_path in category_paths: + print('check links for {}'.format(os.path.basename(category_path))) + + # get entry paths + entry_paths = get_entry_paths(category_path) + + # for each entry + for entry_path in entry_paths: + # read entry + with open(entry_path, 'r') as f: + content = f.read() + + # apply regex + matches = regex.findall(content) + + # for each match + for match in matches: + + # for each possible clause + for url in match: + + # if there was something + if url: + try: + # without a special headers, frequent 403 responses occur + req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'}) + urllib.request.urlopen(req) + except urllib.error.HTTPError as e: + print("{}: {} - {}".format(os.path.basename(entry_path), url, e.code)) + except http.client.RemoteDisconnected: + print("{}: {} - disconnected without response".format(os.path.basename(entry_path), url)) + + number_checked_links += 1 + + if number_checked_links % 50 == 0: + print("{} links checked".format(number_checked_links)) + + print("{} links checked".format(number_checked_links)) + + if __name__ == "__main__": # paths @@ -161,3 +233,6 @@ if __name__ == "__main__": # generate list in toc files update_category_tocs() + # check external links (only rarely) + # check_validity_external_links() + diff --git a/games/rpg/_toc.md b/games/rpg/_toc.md index 6d8bafd6..7a543d42 100644 --- a/games/rpg/_toc.md +++ b/games/rpg/_toc.md @@ -16,10 +16,12 @@ - **[Dawn](dawn.md)** (C++, GPL-3.0, beta, inactive since 2011) - **[Deliantra](deliantra.md)** (C, GPL-2.0, mature) - **[Egoboo](egoboo.md)** (C++, C, GPL-3.0, mature, inactive since 2015) +- **[Erebus](erebus.md)** (C++, GPL-3.0, beta) - **[Eternal Lands](eternal_lands.md)** (C, C++, [Special](https://raw.githubusercontent.com/raduprv/Eternal-Lands/master/eternal_lands_license.txt), mature) - **[Evol Online](evol_online.md)** () - **[Exult](exult.md)** (C++, GPL-2.0, mature) - **[Fall of Imyrin](fall_of_imiryn.md)** (Python, GPL-3.0, beta, inactive since 2009) +- **[Freedink](freedink.md)** (C++, GPL-3.0) - **[FreedroidRPG](freedroid.md)** (C, GPL-2.0, mature) - **[Hero of Allacrost](allacrost.md)** (C++, Lua, GPL-2.0, stable) - **[Ilarion](ilarion.md)** (C++, Java, Lua, GPL-3.0, mature) diff --git a/games/rpg/erebus.md b/games/rpg/erebus.md new file mode 100644 index 00000000..60752c82 --- /dev/null +++ b/games/rpg/erebus.md @@ -0,0 +1,16 @@ +# Erebus + +_RPG (Role-Playing Game), for PCs, smartphones, tablets and handhelds._ + +- Home: http://erebusrpg.sourceforge.net/ +- Download: http://erebusrpg.sourceforge.net/#download +- State: beta +- Code: https://sourceforge.net/p/erebusrpg/code/ci/master/tree/ +- Language(s): C++ +- License: GPL-3.0 + +Uses Qt + +## Building + + diff --git a/games/rpg/freedink.md b/games/rpg/freedink.md new file mode 100644 index 00000000..56f93fd0 --- /dev/null +++ b/games/rpg/freedink.md @@ -0,0 +1,14 @@ +# Freedink + +_Dink Smallwood is an adventure/role-playing game, similar to Zelda (2D top view), made by RTsoft. FreeDink is a new and portable version of the game engine._ + +- Home: https://www.gnu.org/software/freedink/ +- Download: https://www.gnu.org/software/freedink/get +- Code: http://git.savannah.gnu.org/cgit/freedink.git/ +- Language(s): C++ +- License: GPL-3.0 + +May require original content + +## Building + diff --git a/games/strategy/_toc.md b/games/strategy/_toc.md index 17c68241..c9d84c0f 100644 --- a/games/strategy/_toc.md +++ b/games/strategy/_toc.md @@ -6,13 +6,16 @@ - **[Battle for Wesnoth](wesnoth.md)** (C++, GPL-2.0, mature) - **[Birth of the Empires](birth_of_the_empires.md)** (C++, Private use allowed (original artwork under special license)) - **[C-evo](c_evo.md)** (Delphi Pascal, None found, mature, inactive since 2013) +- **[Civil](civil.md)** (Python, GPL-2.0, beta, inactive since 2003) - **[Crimson Fields](crimson_fields.md)** () - **[Crown and Cutless](crown_and_cutless.md)** (C++, Special, beta, inactive since 2006) +- **[Endgame: Singularity](singularity.md)** (Python, GPL-2.0, beta, inactive since 2010) - **[Free Orion](freeorion.md)** (C++, Python, GPL-2.0, beta) - **[FreeCol](freecol.md)** (Java 8, GPL-2.0, mature) - **[FreeRails](freerails.md)** (Java, alpha) - **[Freeciv](freeciv.md)** (C, GPL-2.0, mature) - **[Freeciv WebGL](freeciv_web.md)** (Javascript, Java, AGPL-3.0, mature) +- **[Gigalomania](gigalomania.md)** (C++, GPL-2.0, beta, mature (inactive since)) - **[Glest](glest.md)** (C++, GPL-2.0, mature, inactive since 2009) - **[Globulation2](globulation2.md)** (C++, GPL-3.0, mature) - **[Heroes of Wesnoth](heroes_of_wesnoth.md)** (C++, beta) @@ -38,5 +41,6 @@ - **[Widelands](widelands.md)** (C++, Lua, GPL-2.0, mature) - **[Xconq](xconq.md)** (GPL, mature) - **[Zero-K](zero_k.md)** (Lua, GPL-2.0) +- **[Zetawar](zetawar.md)** (Clojure, MIT, mature) [comment]: # (end of autogenerated content) \ No newline at end of file diff --git a/games/strategy/gigalomania.md b/games/strategy/gigalomania.md new file mode 100644 index 00000000..4dfdd1f6 --- /dev/null +++ b/games/strategy/gigalomania.md @@ -0,0 +1,13 @@ +# Gigalomania + +_A 2D real time strategy Mega-Lo-Mania-like god game._ + +- Home: http://gigalomania.sourceforge.net/ +- State: beta, mature (inactive since) +- Keywords: single player, multi player, RTS, TBS (if none, remove the line) +- Code: https://sourceforge.net/p/gigalomania/code/ci/master/tree/ +- Language(s): C++ +- License: GPL-2.0 + +## Building + diff --git a/games/strategy/spring.md b/games/strategy/spring.md index 9debdfde..49a44a7b 100644 --- a/games/strategy/spring.md +++ b/games/strategy/spring.md @@ -11,7 +11,7 @@ _Game engine for real-time strategy (RTS) video games._ - Language(s): C++, C, Lua - License: GPL-2.0 -See also [Spring 1944](http://spring1944.net/) a special scenario of the spring engine (code: https://github.com/spring1944/spring1944). +See also [Spring 1944](http://spring1944.net/) a special scenario of the spring engine, code: https://github.com/spring1944/spring1944 Or [ZeroK](http://zero-k.info/) another game using SpringRTS.