Pseudo-textbased game engine written with javascript
Aleksi Talarmo 9172001c37 Update 4 years ago
.gitignore initial commit 4 years ago
LICENSE initial commit 4 years ago Update 4 years ago
baseengine.js Fixed permanent events and clearing the screen 4 years ago Patch 1.1 Relase 4 years ago
entities.js First hotfix after release 4 years ago
index.html Created an early version of PropertyTracker 4 years ago
input.js Patch 1.1 Relase 4 years ago
main.js Patch 1.1 Relase 4 years ago
mainstyle.css Patch 1.1 Relase 4 years ago
propertytracker.js Updated README and added License to files 4 years ago

Fable Weapon

Fable Weapon is a text-based game engine created with JavaScript to be easily adaptable to all kinds of websites!

... And it's fully forkable!

Please note: Everything else than the actual engine (baseengine.js, input.js and entity.js, propertytracker.js), is only for the testing interface. You may use it, but I would rather you make another one, a more customized if you decide to use the engine.

Docs updated 8.5.2015, with release of Patch 1.1.

Table of Contents

How to Use


  • Browser that supports JavaScript
  • jQuery

Fable Weapon is made with JavaScript so the HTML part is faily easy, just add .text class to all the areas you want the eventlog to be printed and add .input class to all the areas you want input to be added in.

Now on the JavaScript side, there's not too many commands you should use.

Getting started

To get started, you need to import a few files, baseengine.js is required for the printing and it also requires entities.js to work. Entities.js allows you to use an entity system like Artemis. Input.js is required for any input. So all this means they need to be loaded in a fairly specific order. Propertytracker.js allows you to track some variables on objects and is also no means necessary.

  1. Baseengine.js
  2. Entities.js
  3. Input.js
  4. Propertytracker.js After all this you should be already able to start making your game!

Basic Commands

The regular print command is print_event(arguments) and for arguments it'll take entities and pieces of string. The command clear_events() clears the event screen and print_permanent_event() will print and event that won't be removed by max amount of events (Recommened to use only if max amount of events is smaller than the screen can handle).


print_event("Event !"); // This would print "Event !" on the text areas and return "Event !".
print_event("Also an ", "Event !"); // This would print "Also an Event !" on the text areas and return the text.
print_permanent_event("This event says here forever!") // Permanent events are currently not removable in any way.
clear_events(); // Clears all current events and returns cleared events.

You can also add certain classes to the printed text with "tags" used in strings that are printed, such as <red> Red Text </red>. Currently only colors are supported, but more classes can be added by first importing the class from css and then add it to the "CLASSES_TO_REPLACE" (see below).


print_event("Some text <red>and this is in red.</red>");
print_event("<cyan>And this is in cyan.</cyan>");


There is currently very little configuration to the engine, but more will come in the future.

MAX_MESSAGES = x; // This would set max amount of events that can be posted to x. Default is 20.
CLASSES_TO_REPLACE.push(x); // This would add "x" class for CLASSES_TO_REPLACE to be used in text (<x>text</x>)
    // Please note: the class itself doesn't nessecarily do anything, add it to css and some styling for example,
    // You could also change the default strings in NAME, DESCRIPTION and COLOR. (default "NAME" etc.)

How to create classes for CLASSES_TO_REPLACE (red color for example).


print_event("<red>This should be red</red>"); // Example usage


.red {
     color: rgb(255, 0, 0);


The entitysystem implemented in Fable Weapon very much resembles Artemis, and it is also used in printing. If you wish to print an entity, the entity must have NAME and DESCRIPTION (CString components).

Please note: NAME, DESCRIPTION and COLOR are variables that already exist.

Examples creating an entity:

var entity = new Entity();
entity.add_component("component", new TestComponent());
entity.get_component("component") // returns the TestComponent just created.

Examples for printing entities:

var entity = new Entity();
entity.add_component(NAME, new CString("Some entity"));
entity.add_component(DESCRIPTION, new CString("This is the tooltip description."));
entity.add_component(COLOR, new CColor("green")); // NOT REQUIRED

print_event(entity); // Now this would print "Some entity" in green and on hover it would show tooltip that would say "This is the tooltip description."


The Components are the objects that contain all of entitie's datas. Currently there are only 2 components ready, but they are very simple to create.

Current Components

var name = new CString("Name here") // CString contains only a string and is used for NAME and DESCRIPTION.
var color = new CColor("white") // Color of the entity on event log. You MUST use the colors that are defined above. This component should be saved in COLOR.

Creating a component is also very easy:

TestComponent = function(arg1) { // This is how to create a very simple data container
    this.textvariabe = arg1;

TestComponent.prototype = { // To add functions in it, create a prototype for it.
    testfunction : function(arg1, arg2) {
        return (arg1 + arg2);

// Then just add this component for an entity

var e = Entity();
e.add_component("TestComponent", new TestComponent("Some text!"));

// Then you're done!


Creating input might be easier than you'd think, but it still has some indepth in it.


Menus are no means obligatory, but for later builds of the engine, they are highly recommended. Menus are basically lists of different menu items that are interactive, but later menus will have some features that you wouldn't have without them.

Creating a menu is just easy as:

var menu = new Menu();

Now when using menus and input in general you might want to use a command clear_input_field(). This clears all of the menu items from the field. Also when using menus after creating the menu, at some point you need to call menu.create_menu(), this would actually create the menuitems. And now when adding menuitems you need to call menu.add_menuitem(x) where x is the menuitem to be added.

Now creating a Menu would look a bit like this:

clear_input_field(); // Clears all of the menuitems that are in the field at first.
var menu = new Menu();
menu.add_menuitem(x); // This would add x -menuitem to the menu.
menu.get_menuitem_index("Test"); // This would return the index of the menuitem that is labeled "Test", otherwise returns -1.
menu.get_menuitem(1); // This would return the menuitem at the index 1.


Now creating a menuitem is a bit harder, but it's faily easy aswell.

First thing's first, practically all menuitems have text, function and styling.

  • Text is the text that shows up in the menuitem.
  • Function is the function ran when the menuitem is ran. (Optional argument)
  • Styling is used to add any kinds of css classes etc. to the menuitems. (Optional argument)
  • You can also now of patch 1.1, style the buttons mid-text with tags.

At the moment there are Buttons and InputFields. You can create both as easily as

var button = Button("Button label", function() { alarm("The button was pressed!") }, "red"); // This button is labeled "Button label", is red and alerts "The button was pressed!" when it's pressed.
var inputfield = InputField("Name:", click_action, "green"); // This InputField begins with "Name:" and has no action when pressed. The InputField is green.
var funnybutton = Button("<green>Button</green> <blue>label</blue>", function { alarm("This is a colored button you pressed!") }) // This button is colored with labels.
// The same thing as above, can be done with InputFields too!

Now for both we have some common methods:

button.change_text("New Label"); // This changes the button's label to "New Label"
button.add_styling("blue"); // Adds "blue" class to the button.
button.set_function(function() { print_event("I no longer alert!") } ); // Changes the button's function to now print an event instead of alerting.
button.create_button(); // Creates the button in the input field.

And for the input field we have some special methods:

inputfield.input(); // This would return the text that is in the input field.
inputfield.input("Test"); // This would return the input, but set the input field to "Test" afterwards.

Please note: Also as of patch 1.1, styling of focused / selected buttons is done a little differently, earlier you could've used the :hover, but now you need to use .focused -class. For example:

.focused .red {
    color: (255, 255, 255);

Now this would set focused button with style "red" somewhere in it, to be completely white.

Keyboard Input

Keyboard input was introduced in the patch 1.1, and enables quite a lot of things to be done with the engine. Keyboard input is fairly easy to set up, and very useful for all kinds of situations.

For first, you'll need to enable the actual input by calling enable_input_handling(). Then if you want to enable the pre-made menu-scrolling system (explained more later), call enable_menu_scrolling(up-key, down-key, select-key). These have to be called only once!

Now after these, you should have it ready. The pre-made menu-scrolling system works so, that if you press the keys assigned to up and down, the focus / selection in all the menus move up or down. When you press the select key, all focused buttons are selected (pressed). Keys for the arguments given are always strings, e.g. a, down-arrow, enter, etc.

Now if you would want to create your very own keyboard inputs, that's very easy to do aswell:

enable_input_handling() // Just remember to enable input handling first, so they'll work!
clear_inputs(key) // Clear all inputs for the said key. This key now dows nothing when pressed.
add_input(key, function() { alert("Hey, I was pressed!") } ) // This would now assign an alert pop-up for when the 'key' is pressed.

There are very many pre-made keys, but you can always create your own, by calling add_keyboard_input(keycode, key). Just remember to keep 'key' rather a string, and always get your keycodes from the HTML codes ( use this if none other )

Here are all the premade keys listed:

  • enter
  • 0-9 numbers ( as strings! e.g. "0", "1", etc. )
  • a-z letters ( lowercase letters ! )
  • left-arrow
  • right-arrow
  • down-arrow
  • up-arrow

Property Tracking

Property tracking is probably the most complicated of the components included in this engine. Please note earlier note: The Property Tracking is in NO means necessary, and is a completely optional component.

The most important part of Property Tracking is of course the actual PropertyTracker. For the PropertyTracker's first constructor argument you need yourself a filter how the property tracker knows where you want the properties to. The second constructor argument is optional, and there you need to add all the styling classes you want for all of the items in the PropertyTracker.

The PropertyTracker in itself is fairly simple.

var pt = new PropertyTracker(".property-area"); // creates a regular property tracker which will output in any fields with class ".property-area"
var pt = new PropertyTracker(".property-area", "green"); // creates the same as previous one but this one has class "green" in all of it's elements.

Now the next part is what makes the PropertyTracker a bit complicated, for all the properties you want the PropertyTracker, you need to create a Property for it. Property needs an object to get the property from, and it needs the property in a string. Then you need a key for the property to use later in a string.

var pt = new PropertyTracker(".property-area");
pt.track_property("<KEY>", new Property(object, "property")); // Tracks the property
// Now the PropertyTracker will get when necessary and uses <KEY> to know where to put it.

For the last part in PropertyTracker you finally actually need the elements (text) for it. For example if you'd want the PropertyTracker to show something like this:

Health: 30/50
Mana: 20/60

For this you need to add the elements, and this is fairly easy. After you add the elements and track the properties that you want, you need to create the elements with pt.create_elements() and when you want the properties to be updates (they aren't updated automatically), you need to call pt.update_elements().

var pt = PropertyTracker(".property-area");
pt.track_property("<KEY>", new Property(object, "property"));
pt.add_property_element("p", "The property of tracked property is <KEY>"); // Now this would make a <p> -element in the PropertyTracker and PropertyTracker will replace <KEY> with the property that was set above.
pt.add_property_element("p", "I should be before the first one!", false); // This does the same as the above one, but instead inputs the element in the start.
pt.update_elements(); // Finally we need to update the element
pt.create_elements(); // And then crete the elements, they don't exist anymore before this.

And then you're done!


Fable Weapon is lisenced under GNU GPLv3 and is fully free and available anyone for use. ( With certain specification and requirements )