Code Monkey home page Code Monkey logo

gaiman's Introduction

Gaiman Engine and Programming Language

Gaiman: Text based adventure games engine and programming language

npm Build and test Coverage Status LICENSE GPLv3

Gaiman: Storytelling Text Based Game Engine and Programming Language

Main part of Gaiman is a minimalist, Ruby inspired, programming language. The main purpose of it is to help creating Text Adventure Games. But it can also be used to create any interactive CLI applications (Web Based Terminal applications). It supports browser based CLI applications and in the future also native command line.

Installation

First, you need to install NodeJS. After you're done, you should open terminal and use npm command (that is included with Node).

npm install -g gaiman@beta

Usage

First, create input.gs file with your Gaiman program (you can use one of the examples), and then run:

gaiman -o directory input.gs

This will compile your source file and generate directory/index.html and directory/index.js files. You can open the generated HTML file in the browser and run the game.

When output files are generated you can use this command to run live Web server. This is required to run the example. It's like running a website on the internet.

cd directory
npx live-server

This should open index.html inside your browser. When your app is ready you can publish it with:

Documentation

See Reference Manual on Wiki.

Examples

This is Hello world Gaiman DSL example:

echo get "https://gaiman.js.org/gaiman.txt"
echo* "Hi, What is your name?", 50 # Typing animation with 50ms delay
let name = ask "name? "
echo "Hello $name, nice to meet you."

More advanced example:

if cookie.visited then
    if cookie.user then
        let user = cookie.user
        echo "Hello $user, welcome back"
    else
        ask_details("Welcome back stranger")
    end
else
    cookie.visited = true
    ask_details("Welcome stranger")
end

def ask_details(msg)
    echo msg
    echo "Do you want me to contact you with updates?"
    let confirm = ask "yes/no: ", lambda(answer)
        return answer =~ /^(y|yes|n|no)$/i
    end
    if confirm =~ /y|yes/i then
        echo "what is your name?"
        let name = ask "name: ", lambda(name)
            let valid = name != ""
            if not valid then
                echo "You need to type something"
            end
            return valid
        end
        cookie.user = name
        let email = ask "email: ", lambda(email)
            let valid = email =~ /^.+@.+\..+$/
            if not valid then
                echo "wrong email"
            end
            return valid
        end
        cookie.email = email
        let response = post "/register", { "name" => name, "email" => email }
        if response then
            echo "Welcome $user. You're successfully registered"
        end
    else
        echo "Ok, as you wish. Bye"
    end
end

More examples in examples directory

See Reference Manual for details about the features

Live Demo

See Gaiman language Playground

Live Edit of Gaiman Code: Gaiman programming language Playground Demo Session

Live edit of style Gaiman programming language Playground Demo Session

Roadmap

See Wiki TODO & Roadmap.

Name and Origin

Name came from Neil Gaiman, Author of novels, comic books, graphic novels and films. Great storyteller.

You can read about the origin of the language in the beginning of the article:

Acknowledge

Logo use:

License

Released under GNU GPL v3 or later
Copyright (c) 2021-2022 Jakub T. Jankiewicz

gaiman's People

Contributors

jcubic avatar lijok avatar snyk-bot 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

gaiman's Issues

Dictionaries

Dictionaries should be created using Map or {} decided on runtime which is supported.

  • create inline
let dict_1 = {}
let dict_2 = {
  "ten" => 10,
  "twenty" => 20
}
  • Dictionary access
// access Adapter
function access(object, arg, ...rest) {
    let first;
    if (object instanceof Map) {
        first = object.get(arg);
    } else {
        first = object[arg];
    }
    return access(firt, ...rest);
}

mapping:

  • location.href.baz ==> access(location, 'href', 'baz')
  • location.replace("about:blank") => access(location, 'repalce')('about:blank').
  • settter
  • location.href = "about:blank" ==> location.href = "about:blank"
  • foo.bar.baz = 10 => set(foo, 'bar', 'baz', 10).
function set(object, ...rest) {
    let result = object;
    while (rest.length > 2) {
        const prop = rest.shift();
        if (object instanceof Map) {
            object = object.get(prop);
        } else {
            object = object[prop]
        }
    }
    const prop = rest.shift();
    const value = rest.shift();
    if (object instanceof Map) {
        object.set(prop, value);
    } else {
        object[prop] = value;
    }
}
  • Dict as dict key
let x = {
  "foo" => 10
}
let y = {
  "bar" => 20
}
let z = {}
z[x] = "hello"
z[y] = "world"
z[x] + ", " + z[y]
# hello, world
  • Add key,value for loop
for key, value in {"hello" => 10, "world" => 20} do
   echo "$key => $value"
end

Add Python range function

There will be no standard for C loop. So to interate over numbers there is need to have range function from Python.

Add way for runtime type checking

You should be able to check if something is

  • object
  • array
  • string
  • number
  • null
  • boolean
  • undefined

Best if it's command type that return type but it's not typeof that is not infinitive.

Prevent infinite loops in playground

There should be some kind of guard jus for playground, that will stop long running loops.

Just made mistake and wrote:

let x = 10
while x > 0 do
  echo "NUM: $x"
  x = x + 1 # there should be minus here
end

and it frozen the browser.

Add support for audio

Allow playing sound and music.

  • Came up with syntax.
  • Support for looping (music)
  • Allow to run in background and async

Create interactive playground

It would be nice to have a code editor on one side and a game on the other.

  • Editor
  • Service worker
  • Favicon
  • A way to see generated JS code
  • reset button
  • ZIP download
  • Error messages

Implement tail recursion with trampoline

function calls should return Thunk that should be resolved with the trampoline so you will be able to create real infinite loops. This is important for cases like inn demo:

def ask_color()
    echo "Pick color?"
    let color = ask "color? "
    if color ~= /red/i then
      echo "I like red, it remiding me of sun at sunset"
    else if color ~= /blue/i then
      echo "I like blue, it remind me of sky"
    else if color ~= /black/i then
      echo "I like black it remind me of the darkest night"
    else
      echo "sorry I only know red, blue and black colors"
    end
    echo "Do you want to check another color?"
    let confirm = ask "yes/no? "
    if confirm ~= /yes/i then
      ask_color() # here recursive call should be returned in a thunk
    else
      echo "Ok, have a nice day"
    end
end

Add break and continue statements

let x = 0
while true do
  x = x + 1
  if x > 10 then
    break
  end
  echo x
end

for i in [1, 2, 3, 4, 5, 6, 7] do
   if i % 2 == 0 then
      continue
   end
   echo x
end

Use jQuery for Ajax

jQuery detect mime type of the response and return XML root element, Object or string. THe function do the right thing. It will simplify things, if get and post just return Object if the response is JSON.

You can't use keyword as part of the name

Doesn't work:

input "hello"

part of "in" keyword

def define()
end

define part of def keyword

Whole keyword check need to be refactored. Probably using assertion to test if the final name is a keyword.

For loops

Add support for:

for item in iterator do
   echo* item
end

parse command

Parse string from ask into array of arguments. Possible parse and parse*.

Add automation to the game

There should be a way to run exec and play the game without interaction.
Either as animation or as unit tests.

  • Add way to write unit tests for game, test input and output
  • Add way to animate the game as a demo to show how to play

Here docs as part of expression

There should be a way to call:

let factorial = eval(<<<CODE
(function(n) {
   return Array.from({length: n}, (_, i) => i + 1).reduce((a,b) => a * b, 1);
})
CODE)

this works:

let code = <<<CODE
(function(n) {
   return Array.from({length: n}, (_, i) => i + 1).reduce((a,b) => a * b, 1);
})
CODE

let factorial = eval(code)

Add support for i18n

There should be easy way to translate the output game. Maybe add gettext support.

It may require adding modules.

import "i18n"
import "gettext"

and use:

echo _("Welcome to Gaiman game")

while loop

let x = 10
while x > 0 do
  echo "NUM: $x"
  x = x - 1
end

Write documentation

Add to Wiki or Readme.

  • Create Reference Manual
  • Create Tutorial or Getting Started guide

Add splat operator

Splat should be compiled to rest operator

def sum(*args)
   let result = 0
   for i in args
       result += i
   end
   return result
end

Using current syntax. It should be able to use array.map in the future.

Promisify Array::reduce

After updating Array::map and Array::filter there is need to make reduce work with async functions.

Commands as part of expression

This doesn't work:

echo "<white>" + (ask "? ") + "</white>"

it should parse command inside parentheses as part of expression.

The same

echo* (get "https://jcubic.pl/file.txt"), 100

This may be the same kind of expression

Use ES Modules and Compile output code into ES5

The output HTML should use ES Modules with code as-is and files compiled to ES5 for old browsers.

The goal is to make the game work in IE11. Not many people use it, but some other browsers may not support all the features, like old smartphones. There will be not that much work to support IE11, since jQuery Terminal works in IE11.

  • Compile output JS to ES5 with Babel
  • Use <script type="module" in html

Create UMD file

Create dist directory with a file that can be used in the browser (for the playground).

Add get* and post*

Those will be special case of get and post that will get output as text even if the response is JSON or XML.

Chaining methods

[1, 0, 2, 3, 0, 4].map(square).filter(identity)

arr.map(square).filter(identity)

Execute function from bracket prop property access

Add syntax:

let list = {
   hello => lambda()
     echo "HELLO FROM LAMBDA"
   end
}
list["hello"]()

This is important if "hello" is variable:

let cmd = ask "? "
if type list[cmd] == "function" then
   list[cmd]()
end

Add support for tab completion

Add a way to set completion. Came up with a nice API.

Maybe:

completion ["foo", "bar", "baz"]

let commands = ["foo", "bar", "baz"]

completion lambda(string)
   return commands
end

Support Themes for browser

The js code can add terminal to #term and there can be different themes that user can pick.
Vintage, Forest, Dracula, etc.
There also should be a way to pick window version. There can be modules that will be combined into one CSS and HTML.

Add the way to set css variables in output

Add way to customize output html with custom CSS.
Allow to add:

:root {
  --color: black;
  --background: white;
}

Consider adding tab with custom style, with default colors, that User can change. Similar to config files on Linux.

Add game playthrough gif to readme

Create an interesting example that will showcase the library.

It should:

  • Be relatively short.
  • Has some logic, maybe mini-game.
  • Have Glow style.
  • Have colors.
  • Have Typing animation.

Create a blog

  • Create Jekyll Eleventy blog
  • Write Quick Intro to the language and its history
  • Use storytelling for first blog entry

Add rerun button to playground

I would be easier to refresh the iframe and rerun the terminal. Right now you need to update something in the code (e.g. add and remove space).

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.