forthebadge forthebadge Gem Version

This gem was last updated on the 05.10.2023 (dd.mm.yyyy notation), at 06:29:21 o'clock.

logo

About the games_paradise project

This project will eventually contain some games, some of which are playable, some of which are not. The long-term goal for this project is to not only showcase different games, including bindings, but to additionally explain the relevant parts that led to the design and code in use by these games.

In other words: this project will try to contain information that may be helpful for newcomers (to game design; not newcomers to the ruby programming language).

Note that the term 'games' in this context refers mostly to small games. I do not have the time and motivation to create large games - the time investment would be too high. But the games_paradise project will try to integrate smaller games whenever possible.

Goals and Meta-Goals for the games_paradise project

Over the last ~20 years or so, sort of (back to 2004), I have noticed a LOT of ruby code vanishing from the world wide web.

On top of that, old code written in, say, 2006, often no longer works today; this has been the case with ruby-gtk2 in particular. A lot of the old code no longer works. Porting that old code 1:1 takes quite a bit of time and often is not even possible because associated bindings, such as for gnome, no longer worked.

I think it is rather unfortunate when we lose code that has at one point in time worked in mankind's history perfectly fine - not just in regards to old games, but old code in general. Often the necessary transition-time and time investment spent for making the old code work again isn't that much, if someone would maintain the code every few years. So it is clear that these projects were completely abandoned at some point in time; otherwise these would be maintained every now and then. People move on to do other projects as time passes by - that happens. Sometimes you abandon an old programming language and use a different programming language, so it makes little sense to maintain legacy code that you once wrote.

The wish to have old code still work is thus one meta-goal for the games_paradise project. Ideally we can preserve older games that were written (in ruby), so that future generations of ruby users can benefit from this as well.

There are more goals in addition to that, smaller ones. For example, I would like to model old forgotten games, but without necessarily (re)writing the whole game. I am fine prototyping some game skeletons and collecting information about this in different .rb files or in different .yml (YAML) files. This should make it a bit easier for other people to eventually take up on that task and (re)create these old forgotten games. See also the TODO list of game prototypes in the doc/ subdirectory.

(1) The Hangman game

The classic hangman game! This variant was written by me. It was the first game I put into the games_paradise project, because it is a fairly simple game to implement and I wanted to prototype something, so I started with the hangman game.

Right now a commandline variant exists (at bin/hangman), incomplete ruby-gtk3 bindings to that commandline code as well as incomplete ruby-gosu bindings. The commandline variant should work just fine, though; just call bin/hangman or the hangman.rb file directly.

The ruby-gtk3 bindings work to some extent; you get a top-buffer showing the current hangman progression frame, and you can guess the next character and so forth. Restarting the game works properly as well since as of 2021. Minor things may still be missing, mostly usability improvements. I may get to do so, if time and motivation permits (perhaps!).

If you have the dictionaries gem installed then you can also use a random english word (if it is registered in the dictionaries gem), via this commandline flag:

hangman --dictionary

The commandline variant makes use of a few ASCII "pictures", such as GamesParadise::Hangman::RIP_ASCII_PICTURE signaling the game over state. If you want to make use of the Hangman game in a GUI setting then you may want to prefer using real images rather than ASCII text.

If you rather want to use your own text file, to determine the guessable word in use, you simply pass the file name into hangman, like so:

hangman /Depot/foobar.md

The ruby code will then randomly grab a line from that file. I recommend one-word-per-line; this makes it all simpler.

To query whether a single character, such as 'a' is included in the word-that-is-to-be-guessed, you can use the following method on an instance of class Hangman:

is_this_character_included?
is_this_character_included? 'a'

To start the ruby-gtk3 bindings, you can try this:

hangman --gui

Use the entry in the middle as user input. After typing the character, hit the enter key or the button to submit input.

You can also tap into the dictionaries gem via the GUI, by using a check-button. By default it is not active, so the user has to click on it in order to enable the use of the dictionaries gem.

(2) TicTacToe

A simple game. Right now a ruby-gtk3 widget exists, and a commandline variant. I intend to add a ruby-gtk2 implementation and a variant with gosu as well, one day. :)

(3) Minesweeper

Many years ago I wrote a minesweeper variant in ruby-gtk2.

In February 2021 I adapted the code to ruby-gtk3. Unfortunately there are some bugs, so it is currently not playable, but you can still start it and have a look.

Eventually I'll get to fix it and clean it up, but for now I just wanted to integrate it as-is.

If you need a base map for your own code in regards to minesweeper, have a look at class GridPlacer. This one will place the mines for you, so you only have to handle the buttons in a GUI for that.

There also exists a 'toplevel' method for placing a grid, which can be used like in this way:

require 'games_paradise'

GamesParadise::Minesweeper.grid(n_mines: 20, n_fields: 100)

The field should ideally be a quadrant; at some later time I may add rectangles as well.

If you want to use Emojis rather than images for a minesweeper clone, you could use the following emojis perhaps:

'' # For a flag.
'💣' # For a bomb.

(4) Tetris

A tetris clone exists for gosu (gosu-bindings). Incomplete ruby-gtk3 code exists as well.

This isn't very pretty so far and not documented well, but it works somewhat. I may improve on this in the coming months.

One tiny improvement that was made was that a "help" menu will appear if you press the "H" key. That way you can disable the sound (via the "P" key). I may have to replace the audio file with a smaller, and less noisy one though ...

(5) Mastermind

A prototype exists in ruby-gtk3 for mastermind. It works somewhat, but isn't very well-polished. My goal here is to clean the code base up, and then add bindings to gosu.

(6) 1010

This game is a bit inspired by tetris, but it is a tile-based puzzle game where you, as the player, place tetris-like objects onto a 2D grid. The main implementation is for a single player. The default square grid is a 10x10 cells.

The player is presented with a random selection of tile patterns of various shapes, 3 at a time, which are to be placed on the board, one by one. If the tiles consume an entire row (or column), without any empty cells in between, the row (or column) is cleared up so that more tiles can be placed.

Each cell consumed by the tile counts towards the score of the game.

The aim is to place as many tiles as possible to increase the net score. In its most simplest form, each cell adds 1 point to the score. A variation of the game can be to assign different points for each color.

You can press and hold the H key to see help-menu at any moment in time when running this game.

Currently some gosu-bindings exist to 1010, but they are not necessarily perfect. Ideally we can also offer ruby-gtk3 bindings in the long run - let's see.

The original code was written by shanko, and you may be able to see the repository here:

https://github.com/shanko/1010

The modifications in games_paradise are mostly some style-clean up and more documentation within the .rb files.

The licence for 1010 is MIT.

(7) Memory games

Memory games are, for example, where you have to remember two cards, click on both cards, and then see how these are removed from the available card pool. Currently a simple version of this exists, for gosu.

The original variant was written by Boyan R.:

https://github.com/boyanpn/gosu_memory

The code in games_paradise has been updated a bit; more comments were added as well, and I removed a few global variables (but there are still some left, duh ...).

If you want to start that game with a specific number of cards, you could use this commandline invocation:

memory --ncards=18

Note that the game map is currently too small to display lots of cards; and we'd need to add more card-images too. But in principle this support has been added by me in February

  1. Small improvements for the win! \o/

(8) Aero-Exploder

This variant was originally based on the code written by SavageHolycow ( https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?tid=1397 ).

It also used lots of global variables, which is not ideal. I think many contributions come from folks who do not really know ruby that well. There is only rarely a need for a global variable really.

(9) Battle City

This is just a collection of some tanks trying to attack your home base, with you attempting to defend it.

The original game was found here:

https://github.com/kcsheng/battle_city_I

I did not modify it much at all other than adapting the ruby code a bit.

(10) Duck Hunt Calculator

The project originally was created by bestguigui, as a math-exercise trainer, and described here at: https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?tid=1391

The idea is quite nice; in the long run perhaps I will replace this with a non-animal or something rather than ducks, and perhaps add more difficult calculations with different levels. But for the time being this shall suffice as it is.

(11) Billiard

The project originally was created by Makki and mentioned here at: https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?tid=1296

Note that from a historic point of view, there used to be tons of billiard-like games before. Sometimes they had interesting names, such as Arcade Snooker.

The current version (in August 2021) looks like this:

Tons of small things are missing - for instance, counters on the top right to indicate points, and how many shots with the cue it took. Also player names and multiplaying (switching turns).

The code for this game lacks documentation, though, and has to be re-organized. Ideally we should move this into general methods, some toplevel-methods for calculating arcs and torque. But for now I'll keep it as it is - we progress in baby steps here!

(12) Maze Puzzle

Not sure yet whether to keep this one or not. When decided to keep, this stub will be expanded.

The original code can be found here:

https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?tid=1344

and here

https://github.com/at-cuongtran/a_maze_ing

(13) Garden Hero

This game, available from https://github.com/zhzhussupovkz/garden-hero, under the MIT license, has been written by Zhassulan Zhussupov.

I included this into the bundle here, largely for two reasons:

a) It reminds me of the original final fantasy variants on the gameboy, a long time ago. May be useful to showcase a game that taps into that theme.

b) I think the graphics but also the movement-path as such could be improved in a general way, so as to allow people to more easily generate similar games.

(14) ChinguRoids

Under the MIT licence. Not yet sure whether it will be retained as part of the games_paradise project, though. A lot of the code has to be polished .... hmmmmm.

(15) Godmode

This is an idea for a game where heroes fight in an arena.

It will be a bit more complex than my other games, so this will all take time - it is very incomplete right now.

(16) ParticleSimulator

This is just a demo, mostly, to show how particles float.

In the long run I may add more options to control it, different shapes and so forth - but for now this is really just based on code written by someone else for the most part.

(17) Kaiser

This is unfinished - an old strategy game. Kaiser is german for emperor. Your goal is to work up your way towards becoming the new kaiser, before your own demise (e. g. natural death).

This is currently an unfinished game, as said, but you could look around on the www to see for old links, such as the following, to get an idea how it was played:

http://www.kaiser2.de/kaiser_2_das_spiel.htm https://www.c64-wiki.de/images/3/39/Kaiser_Animation.gif

Todo list:

  • Add libUI bindings.
  • Add fxruby bindings.
  • Add tk bindings.
  • Add www variants for .cgi and sinatra.

The licence for the games_paradise project

I thought for a while whether to use GPL or LGPL for the games_paradise project but then decided against it, and opted for MIT instead.

The reason is that most of the games published in ruby are under the more liberal MIT licence. I like the GPL too, but I think for an "umbrella" project that tries to gather as many (playable) games as possible, it is better to use a less stringent licence than the GPL.

You can read up on the MIT licence here:

https://opensource.org/licenses/MIT

The most important part is the "no warranty" clause, aka to translate this into layman terms, "use at your own risk".

Project-policy for images distributed via this gem

This gem comes with several images; some are more generic, whereas others are more specific to a particular game at hand.

There are different ways how images could be handled. A simple way would be, for a given game, to put all assets (including images) into one directory, together with the source code. This then makes it easier to distribute the games in a standalone manner.

However had, the games_project is an umbrella project; it tries to share code across different games, in order to write (and use) less code. The same approach is applied to images - whenever possible, images should be re-used.

All images should be put under games_paradise/images/. If they are generic and re-usable, they should be put under misc/. If they pertain to a particular game, a subdirectory should be created under that directory, with the same name as the game itself.

I wanted to document this new policy, so that eventually everything within this project can be aligned to that policy. Thus, enforcing consistency.

History of some of the games

This subsection here mentions a few games, in particular when they are distributed within the games_paradise project.

The classical Memory game is also called concentration.

Archon: The Light and the Dark was developed by Free Fall Associates and distributed by Electronic Arts. It was originally developed for Atari 8-bit computers in 1983.

Tetris first appeared in 1984.

Defender of the Crown was released on Commodore Amiga in 1986.

Hints, Tipps and Tricks for Gosu

You can create a borderless Gosu::Window via borderless: true. This will hide all window chrome. You can toggle this at a later time, if you want to, via .borderless=.

If you want to mirror a sprite then you can use the parameters center_x as well as center_y before the scale parameters.

Hints, Tipps and Tricks in general when designing games

  • Ideally try to store the dataset-assets for your game in a neutral format, rather than, say, hardcode them into .rb files. YAML is quite well-suited for this, but XML, despite being exceedingly verbose, may also be useful.

  • Separate concerns and aspects whenever possible. Try to build many small components and slowly put them together rather than build monoliths that are hard to decouple again at a later time.

  • If you can fake it, then fake it! This refers to trying to optimise on what is necessary, and if it is not necessary then you do not necessarily have to display it on the game map.

Solitaire

Since as of August 2022 a prototype for the Solitaire card game, including images, has been added. This does not currently work, but the foundation for this card game has been added, so expect this to work eventually.

Games Timeline

This is just a timeline of games that were interesting to me, from a historic point of view.


# =========================================================================== #
# === games_timeline.md
#
# This file lists some interesting or important games that I may have
# played in the past.
# =========================================================================== #
Space Invaders:                                                     01.04.1978
King's Quest I:                                                     10.05.1984
The Bard's Tale:                                                    1985
Ultima IV: Quest of the Avatar:                                     November 1985
Arkanoid:                                                           26.04.1986
Leisure Suit Larry in the Land of the Lounge Lizards:               05.07.1987
Ultima V: Warriors of Destiny:                                      March 1988
Leisure Suit Larry Goes Looking for Love (in Several Wrong Places): 01.10.1988
Lords of the Rising Sun:                                            1989
SimCity:                                                            02.02.1989
Populous:                                                           05.06.1989
Prince of Persia:                                                   03.10.1989
Warlords:                                                           1990
Ski or Die:                                                         1990
Ultima VI: The False Prophet:                                       01.06.1990
Wing Commander I:                                                   26.09.1990
Stunts:                                                             01.10.1990
The Secret of Monkey Island:                                        October 1990
King's Quest V:                                                     09.11.1990
Lemmings:                                                           14.02.1991
Sid Meier's Civilization:                                           1991
Ultima: Worlds of Adventure 2: Martian Dreams:                      1991
Might and Magic IV: Clouds of Xeen:                                 1992
Dune II:                                                            December 1992
Das Schwarze Auge: Die Schicksalsklinge:                            01.04.1992
Ultima VII: The Black Gate:                                         16.04.1992
Space Quest V: Roger Wilco - The Next Mutation:                     05.02.1993
Alone in the Dark:                                                  1992
Mortal Kombat II:                                                   1993
Alone in the Dark 2:                                                1993
Warlords 2:                                                         1993
Betrayal at Krondor:                                                22.06.1993
Master of Orion:                                                    06.09.1993
X-COM: UFO Defense:                                                 01.03.1994
Alone In The Dark 3:                                                1994
Metaltech: Earthsiege:                                              01.07.1994
Ultima VIII: Pagan:                                                 15.03.1994
Prisoner of Ice:                                                    01.01.1995
Battle Isle 3: Shadow of the Emperor:                               1995
X-COM: Terror from the Deep:                                        01.07.1995
Prisoner of Ice:                                                    20.12.1995
Earthsiege 2:                                                       01.03.1996
Fantasy General:                                                    01.07.1996
Schatten über Riva:                                                 01.12.1996
Master of Orion II: Battle at Antares:                              16.12.1996
X-COM: Apocalypse:                                                  30.06.1997
Dungeon Keeper 2:                                                   28.06.1999
Planescape: Torment:                                                12.12.1999
Diablo 2:                                                           29.06.2000
Baldur's Gate II: Shadows of Amn:                                   01.09.2000
Warcraft III:                                                       05.07.2002
Chicago 1930:                                                       01.11.2003
Sid Meier's Civilization IV:                                        25.10.2005
Neverwinter Nights: Diamond Edition:                                01.09.2005
Sid Meier's Civilization V:                                         21.09.2010

Guidelines for using Gosu

The following section just collects some hints offered by other ruby users over the years in regards to Gosu.

They are listed here without any sorting done really.

  • Do not draw anything that is not on the screen. Only draw what the player can see, unless otherwise ncessary.

  • You can not call draw() methods from within the main update() method.

Guidelines for using the custom modifications in games_paradise/modifications/

The games_pardise gem comes with a few modifications to module Gosu. This has been done to give you the option to use a nicer, shorter API, in addition to the official upstream API.

For instance, the regular API for setting a title goes via:

require 'gosu'

class GameWindow < Gosu::Window
  def initialize
    super 640, 480
    self.caption = "Gosu Tutorial Game"
  end
end

If you use the custom modifications then you can simply use:

set_title "Gosu Tutorial Game"

instead. This may not be a huge gain, but it is nonetheless fairly useful.

To require all custom modifications for Gosu you can require the following file (that is, simply use the require line that is shown below):

require 'games_paradise/requires/require_the_custom_gosu_modifications.rb'

To make this even shorter, you can use the other require file:

require 'games_paradise/requires/require_the_custom_gosu_modifications_and_gosu.rb'

This has require 'gosu' on top, so you can save one require line if you use this.

The .rb files under games_paradise/modifications/gosu/ have various additional code that may be useful for you. Not all of these are documented on the page here, but you may be able to use some of them re-used in different projects that I have created in the past.

For instance, rather than creating a new gosu image via:

image = Gosu::Image.new("media/space.png", tileable: true)

You could use this alternative:

image = image("media/space.png", tileable: true)

Yes, it is not a huge "win", but it leads to slightly shorter code nonetheless which is not bad, in my opinion.

Gosu::Image

Using images is quite central to gosu. You can draw a new image onto the screen via .draw().

Example:

.draw(x, y, z = 0, scale_x = 1, scale_y = 1, color = 0xff_ffffff, mode = :default)

This will draws the image with its top left corner at (x, y).

tileable: true is specifically used for background images and map tiles.

What is a sprite?

A sprite is a game object that contains location data. Typically it is an image, with a rect-coordinate. It may also exhibit certain behaviour.

Baldur's Gate 2 Enhanced Edition

As I quite liked the EE (Enhanced Edition) of Baldur's Gate 2, and there is a lot of mod-related content out there, I decided to write some helper-code in ruby for this game.

The code for this can be found here:

games_paradise/baldurs_gate/baldurs_gate.rb

There is also a webpage distributed within this gem, under:

games_paradise/www/baldurs_gate2/

You may have to extract the .tar.xz file, to get access to the .md file that contains a LOT of information, as well as the .cgi (and .sinatra) application that runs the content of this .md file - and more. (This requires installation of the gem called cyberweb.)

You can find some code in the first .rb file, such as this toplevel method:

GamesParadise::BaldursGate.download_mods

To download all mods I find useful. Simply adjust the Array that is passed to this method if you want to use different mods. The installation order is important, by the way - some mods need to have other mods installed before you can install them.

GamesParadise::VierGewinnt

Vier Gewinnt was a fairly popular game back in the days in german-speaking areas.

In December 2022 a commandline variant was added for this game.

It looks like this:

It can be invoked from the commandline via:

games_paradise --vier-gewinnt # The '-' can be omitted, of course.

At a later time some GUI code may be added for this. For now, though, it'll remain as this.

Note that a variant for jruby exists at well, under:

games_paradise/gui/jruby/vier_gewinnt/vier_gewinnt.rb

GamesParadise::Minesweeper::Terminal::CLI

You can run bin/minehunter to start a minehunter (minesweeper) terminal game. This requires the installation of various tty-gems.

It looks like this right now:

Contact information and mandatory 2FA coming up in 2022

If your creative mind has ideas and specific suggestions to make this gem more useful in general, feel free to drop me an email at any time, via:

shevy@inbox.lt

Before that email I used an email account at Google gmail, but in 2021 I decided to slowly abandon gmail, for various reasons. In order to limit the explanation here, allow me to just briefly state that I do not feel as if I want to promote any Google service anymore when the user becomes the product (such as via data collection by upstream services). I feel this is a hugely flawed business model.

Do keep in mind that responding to emails may take some time, depending on the amount of work I may have at that moment.

In 2022 rubygems.org, or rather the corporate overlords who control the rubygems.org infrastructure these days, decided to make 2FA mandatory for every gem owner eventually: see https://blog.rubygems.org/2022/06/13/making-packages-more-secure.html

Mandatory 2FA will eventually be extended to all rubygems.org developers and maintainers. As I can not use 2FA, for reasons I will skip explaining here, this means that my projects will eventually be taken over by shopify (or, correspondingly, whoever effectively controls the rubygems.org ecosystem). At that point, I no longer have any control what is done to my projects since shopify (respectively those controlling the gems ecosystem) took away control here. Not sure at which point ruby became corporate-controlled - that was not the case several years ago.

Ruby also only allows 2FA users to participate on the issue tracker these days:

https://bugs.ruby-lang.org/issues/18800

(Note that this was changed a few months ago, so the last part is no longer valid - it is possible to register again without mandating 2FA. I will retain the above notice for a bit longer, though, as I feel we should not restrict communication via mandatory authentification in general. Fighting spam is a noble goal, but when it also means you lock out real human people then this is definitely NOT good.)