Code Monkey home page Code Monkey logo

goby's Introduction

Goby Build Status Coverage Status

Goby is a Ruby framework for creating CLI-based role-playing games. Goby comes with out-of-the-box support for 2D map development, background music, monster battles, customizable items & map events, stats, equipment, and so much more. With thorough testing and documentation, it's even easy to expand upon the framework for special, unique features. If you are looking to create the next classic command-line RPG, then look no further!

Goby will always be free and open source software. If you have any questions, please contact [email protected].

Example Games

Interested to see what you can do with Goby? Look no further!

  • Ayara: an exploration-based RPG that takes place in a city.
  • Ostrichland: the precursor to the Goby framework!

Getting Started

In order to start using Goby in your application, follow these instructions:

Add this line to your application's Gemfile:

gem 'goby'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install goby

Contributing

Thank you for your interest in contributing! Please read our guidelines before sending a pull request.

Documentation

We use YARD for documentation. In order to generate the documentation (which will be stored in the doc/ directory), run the following command in the project's root directory:

$ yardoc

goby's People

Contributors

brianhgrant avatar dandobrick avatar darkstego avatar dinocosta avatar fingrayson avatar flpcury avatar gintavang avatar jamesball27 avatar jamessral avatar jcreed avatar jeff-hostetler avatar jessecanderson avatar jupiterliketheplanet avatar lsribeiro avatar mehtaculous avatar morrme avatar nskins avatar rdavid1099 avatar ryancoopersmith avatar ryanflach avatar schuyler4 avatar scosbet avatar shyam12860 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goby's Issues

Implement the battle command 'Use'

Entities should be able to use items in battle. This should be abstracted into the Entity class so that Monsters can override the implementation (default is randomly?), and Players will require input.

Monsters drop treasures

After defeating a monster in battle, there should be a chance of receiving a treasure (Item).

Monsters should be endowed with some data structure that holds all possible treasure drops. In addition, each treasure should have some probability of actually being dropped. The first step is to randomly decide whether or not the user should obtain an Item. If not, proceed as before. If so, then sample the distribution of possible drops to determine the actual reward. Show some output about it and add it to the Player's inventory.

New preset game

The current preset game does not thoroughly show off the many features of the framework.

More battle commands for monsters, quests from NPCs, events, etc.

An hour of play time in the preset game should suffice in giving the user a thorough experience.

Experience / Leveling system

There should be a system for the player gaining experience and leveling up stats. Perhaps, in general, entities will be assigned a level depending on the total of the stats?

One possible solution for the player is a class system. The player's class would contain the following:

  1. A function that defines the amount of experience needed to reach a level. Traditionally, such a function would be exponential.
  2. An array of hash objects (like Equippable's stat_change) that define the change in stats at each level. Alternatively, a linear progression would be simpler but more limiting.
  3. Other neat things.

To be continued...

Send pull requests to the level-system branch.

Write script to delete preset data

There should be a script to delete the preset game so the end-user can develop his/her text-RPG from a clean slate. The script should go in a new directory, probably called scripts.

Functions for positive & negative responses

It would be nice to have two sets - one for positive responses and one for negative responses. These could be used for accepting user input on decision prompts (yes or no). Then there would be no need to list the options at the end of each prompt.

EDIT: see my response below for an updated implementation idea.

Send pull requests to the y-n-responses branch.

Refactor equip system

The system for equipping items needs refactoring. There's currently too much code duplication, and a better solution for this would improve our codebase tremendously.

Use a different separator between each special command

When showing special commands, use a different separator between each command. Currently, there are semicolons between each command. The code will be in display_special_commands which is located in lib/world_command.rb.

Here are some example tests that you should add to ensure the correctness of the implementation:

When there's one NPC on the Tile (such as on Donut Field):

Change the old version:

* Special commands: talk;

to the following:

* Special commands: talk

Here's a better example for the use of the separtors, which can be found where the Shop and Hole on Donut Field are found:

* Special commands: shop; dig;

to the following:

* Special commands: shop - dig

or perhaps this:

* Special commands: shop, dig

Do whichever you think looks better.

There are some examples of using RSpec for checking output in spec/Entity/player_spec.rb. See the tests for choose_attack and choose_item_and_on_whom.

Override 'to_s' for BattleCommand and Item

The implementation of 'to_s' should just return the respective name of the object. This addition will allow us to merge functions like 'use_item_by_object' and 'use_item_by_string' into one function: 'use_item.'

Auto events

Some Events may need to be triggered automatically. For instance, an NPC may require a fee to cross a particular Tile. Upon moving to that Tile, the Event must start running.

One idea for the implementation would be to add an auto_event member variable (of type Event) to Tile. Upon moving to the Tile and seeing that auto_event is not nil and also visible, run auto_event.

Send pull requests to the auto-events branch.

Chance of Escape should depend on agility levels

Currently, the probability of Escape (in battle) depends on the enemy's HP, which makes it difficult at the beginning of battle. Instead, the probability should use the same algorithm as player_first? in lib/Entity/player.rb. Perhaps this means that the function should also be renamed.

Write more tests for Player in player_spec.rb

There need to be tests for the following functions: move_to, move_north, move_east, move_south, and move_west. Suggestion: define a simple map at the top in a before(:all) block.

Determine environment in type() function

In util.rb, we have a function called type() that sleeps between the output of each character. Unfortunately, it's not very good for testing since it slows down the test suite. Is there some way to determine the environment (possibly whether the code is running via ruby vs. rspec) in Ruby? I think in Rails there is an equivalent method called rails.env but clearly it can't work here.

If so, then we can sleep only when the environment is ruby and not rspec. Then type() (and certain other methods) would be testable, which would be quite nice.

EDIT: http://stackoverflow.com/questions/24932504/detect-that-code-run-by-rspec-ruby

Provide descriptions in 'help' command

In display_default_commands, we should provide some brief statement about what each command does.

Also, reformat display_special_commands so that the commands are displayed on one line with the text ' * Special commands: '.

Change default parameters of Entity and Player

It is important that the default Entity has the basic stats to fight. For this reason; max_hp, hp, attack, and defense must all change to have default values of 1.

In addition, it is not right that the default Player has pre-defined "good starter" stats. Thus, the Player constructor should inherit those stats mentioned above from the Entity. Additionally, the same can be said of its default battle commands. Change that variable to be 'Array.new.' See the Monster constructor for how this can be done.

Finally, in main.rb, change to those stats from the "old" Player constructor to be the same for the 'player' object in our preset game. This change is content-based so it does not seem that the framework is forcing those stats & commands for the end-user's game.

To summarize:

  • Change the default constructor of Entity's test (enitity_spec.rb) to account for the above changes;
  • Change the default constructor of Player's test (player_spec.rb) to account for the above changes;
  • Change the default values of Entity (entity.rb) as necessary;
  • Change the default values of Player (player.rb) as necessary;
  • Edit main.rb as described.

Case-insensitive world commands

When the player is on the world map, commands should be interpreted case-insensitively. Change the function interpret_command in lib/world_command.rb so that each command is interpreted case-insensitively.

Use the casecmp function of String. Also, it may be necessary to change from using switch-case statements to if-else statements.

Agility attribute for Entity & Battles

We should implement the agility member variable for Entity. Agility will be used to determine who goes first during a turn. Possible algorithm:

  1. sum = player.agility + monster.agility
  2. Choose a random number from 0 to (sum - 1).
  3. If the number < player.agility, then player goes first. Otherwise, monster goes first.

Such an algorithm uses the ratio to decide who goes first. Additionally, there is a more equal playing field since it is not guaranteed that the one with higher agility will always go first.

It will also be important to provide a test suite for this new attribute.

'Graphic' variable for Tile

There should be a way for the user to specify what character to use when printing a Tile on a Map. This allows people to create much more beautiful Map art.

Additionally, the Player's print_map function must be updated for the new method of obtaining the graphic. As for the key/legend, perhaps it will be removed.

Helpful text after eating food

The amount of HP recovered should be nicely displayed after the entity eats some food.

A good formatting will display (1) the entity's name, (2) the food's name, and (3) the amount of HP recovered, such as: "Player1 uses Donut and recovers 7 HP!"

Additionally, the next line might show the current HP (divided by max HP) as: "HP: 92.5/100"

Other formats are also acceptable.

Mark files containing preset data

All of the files containing preset data should have a header at the top that indicates the class (and anywhere the class is used) can be deleted without corrupting the framework.

Argument in update_map

We should allow Player.update_map to accept an argument of type Couple(Integer, Integer). This argument provides the y-x coordinates for around which Tile to update the 'seen' attribute on the Map. It should be fairly straightforward since the function implementation is the same - it just needs to accept that argument. See lib/Entity/player.rb. Include tests.

No documentation on bundling before running sample game.

I got stuck for a few minutes trying to run the sample game. I didn't realize that there was a gem in the Gemfile, deep_clone, that I needed to bundle install. I will add a quick note to run bundle install to the Preset section of the documentation.

Remove impassable boundaries around map

We should not require that the user needs to place impassable tiles around the entire map. Instead, it would be better to just check that tiles are within the x-y bounds of the map. If they are, then we can check if they're passable or not.

Use keyword arguments for default parameters

Unfortunately, the current codebase does not use default parameters in a consistent manner. Both of the current "methods" have bugs, which is why I had been switching between these methods of using default parameters.

To remedy this problem, a good solution seems to be keyword arguments (named parameters):

http://brainspec.com/blog/2012/10/08/keyword-arguments-ruby-2-0/

This provides the true behavior of how default parameters should act.

This also means all the documentation will need to be updated.

In addition, we will need to specify in the Gemfile that at least Ruby 2.0 is required.

Display instructions after exiting the bakery

When I first encounter Bob's bakery and type exit, it just gives a new line.
It would be helpful to display the available commands at that point. My inclination was to type "exit" again which wasn't a valid command.

Welcome to Bob's Bakery.
Current gold in your pouch: 0.
Would you like to buy, sell, or exit?: exit

exit

That isn't an available command at this time.
Type 'help' for a list of available commands.

Remove Tile equality operator

There is no natural reason to compare equality of Tiles. Thus, we should remove Tile's equality operator. I believe it exists only for testing purposes... for those tests, just compare something about the Tiles rather than using equality.

Add NPC and armor shop to preset game

  • There should be an example NPC standing around Donut Field somewhere.
  • There should be an armor shop that sells the new types of Equippables.

These additions will show off more of what the framework has to offer.

Abstract battle() method

It would be better to abstract the batte(Monster) method in the Player class into the Entity class. That way, Player can face Player and Monster can face Monster.

Additionally, there's some repeated code in this method so we can try cleaning it up.

Update Entity function "print_status"

Initially, the only available subclasses of Equippable were Weapon and Helmet. After fixing issue #20, we now have Shield, Torso, and Legs.

The "print_status" function of Entity should be updated to display the names of those new subclasses and the currently equipped item (in a similar fashion to Weapon and Helmet).

Remove dependencies on preset data from test suite

The preset data should not be used in the test suite. Then the user will be able to delete the preset data without affecting the internals. Some problems are in entity_spec.rb, wherever "Kick.new" is used. There are possibly other offending tests as well.

Remember previous commands

Maintain a history of previous commands so that the user can use the up and down arrow keys to use scroll through those commands and re-use them. The data structure maintaining the previous commands does not need to be stored on disk; for now, it should be only available in the running process's address space.

Basically, it should have the same behavior as that in the Shell, but it doesn't have to be persistent across separate processes.

Helpful text after dropping an item

On the world map, the player is allowed to drop (throw away) items that are not needed. There should be a short line of text following the command that indicates successful drop of the specified item.

The code for this issue will be written somewhere around lines 100-110 of lib/world_command.rb.

More subclasses of Equippable

We should provide more subclasses of Equippable. Some examples would be the following:

  • Shield
  • Torso
  • Legs

I assume that the implementations will be identical to that of 'Helmet.'

Instructions when starting the game

I started playing the example game and the first thing I noticed was that there were no instructions on how to play. I think you can kind of figure out how to play, but it would be nice to know before you start playing.

I like that when you type in "help", that all the default commands are brought up. I think it would be helpful if when you started the game that it 1) Shows you the default commands and 2) Tells you the point of the game and 3) Give a description of all the things like HP, Attack and Defense. Also, quit should be added to the default commands.

Guarantee sorted battle commands by constructor

Regardless of the order in which battle commands are passed into the Entity/Player/Monster constructor, the commands should be in sorted order once the object is created.

  • Edit each of the custom constructor tests for Entity, Player, and Monster so that the constructor passes through a list of commands (whose names are) in unsorted order. The tests should then "expect" that the battle commands are in sorted order after the corresponding object is created.
  • Verify that the new tests are passing since this should already be implemented.

Fix print_attacks_with_stats

It may be difficult to implement this function since not every battle command is an attack. Hopefully there is a fix without directly referencing the 'Attack' class in entity.rb.

Tests for equipping Shield, Torso, and Legs

In entity_spec.rb, within the context of "equip item," there should be three new tests written to ensure that each of these subclasses (Shield, Torso, and Legs) are correctly equipped and alter the stats appropriately.

These tests will probably be identical to those already existing and having the same purpose for Weapon and Helmet.

Code Cleanup

I noticed a lot of this in the code:

if (!something_that_may_be_nil.nil?)
  code_goes_here
end

But this can be made a little more readable as:

if something_that_may_be_nil
  code_goes_here
end

This is a simple change, and I will have a PR for it soon.

If this was an intentional design choice, I apologize.

Equality operator for Tile

Write the equality operator (==) for Tile. Examples can be found in item.rb and event.rb. Tiles will compare only their 'passable,' 'seen,' and 'description' attributes for now.

This is necessary for issue #1.

Replace StatChange with Hash

StatChange is a horrible data structure. I realize this now.

I believe there should be a way to replace it with Hash....

There will also be a much better implementation of alter_stats in the near future......

BGM mechanic

It would be really cool if we could implement background music in our framework. This would need to support at least the following two features:

  1. BGM variable for the Map class that starts playing once the player moves onto the map.
  2. Some way to start and stop BGM through Events.

The music should repeat naturally.

Send pull requests to the bgm branch.

Include Escape and Use with framework

Escape and Use are fairly common commands in battle so we should probably include these with the framework (instead of just preset data). This means:

  1. Documentation
  2. Tests
  3. Remove from clear_preset script
  4. Etc. ?

Randomize attack damage

Currently, the amount of attack damage done in battle is deterministic.

There should be a random element in the calculation to spice things up.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.