npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-combo-script

v0.1.0

Published

Tiny script language to describe gamepad command input

Downloads

3

Readme

combo-script

combo-script is light-weight and extensible script language to describe gamepad command input.

It also supports validation to prevent logically inconsistent operations(duplicate or unable button push or stick operation etc).

See DEMO.

Install

npm -i ts-combo-script

Cheatsheet

1. Button operations

Push

If just single button name is described(for example, A), it means pushDown(A) and pushUp(A).

A

Note that all button names are case insensitive. So you can write both A and a.

PushDown, PushUp

Use pushDown or pushUp function to describe push-down or push-up event separatedly.

pushDown(left), pushUp(left)

Note that function names are case insensitive, so you can write pushDown or pushdown.

Push multiple button

You can describe multiple pushing by using tuple like this.

(A, B)
(right, down)

(A, B) means pushing down A and B at the same time(and pushing up A and B at the same time).

Keep pushing(while doing something)

You can use special syntax(called holding syntax) to describe this situation. For example,

(a, b) { rotateL(0, 180), x, y }, L1

It means,

  1. Keep pushing a and b while
    • Rotate left stick from 0deg to 180deg
    • Push x
    • Push y
  2. Push up a and b
  3. Push L1

Selective operation

You can describe selective operation(like A or B) by using or idiom.

rotateL(0, 90), or(triangle, circle)

It means,

  1. rotate left stick from 0 degree to 90 degree.
  2. push triangle or circle button.

Note that if you use or inside multiple push like this...

(a, b, or(x, y))

it's disassembled to following operation like set operation(a and b and (x or y))

or((a, b, x), (a, b, y))

2. Stick operations

Rotate

Rotating stick is described by rotateL(for left stick) or rotateR(for right stick) function.

rotateL(90, 180)

It means rotating left stick from 90deg to 180deg.

Move

Moving stick is described by moveL(for left stick) or moveR(for right stick) function.

moveR(90, 180)

It means moveing right stick from 0deg to 90deg.

Set

Tilting stick is described by setL(for left stick) or setR(for right stick) function.

setR(90)

It means tilting right stick to 90deg.

Unset

Releasing stick is described by unsetL(for left stick) or unsetR(for right stick) function.

unsetL(90)

It means release right stick from 90deg pos.

Touch

Touching stick in any way is described by touchL(for left stick) or touchR(for right stick) function.

touchL(), touchR()

3. Helper message

You can output some helper message by using string literal enclosed by " or '.

"Input quickly!", left, circle

Or you can use info, warn, error functions.

info("this is info"), warn("this is warning"), error("this is error")

Compile combo-script

import { compile } from 'combo-script'
const { ast, errors } = compile("(a, b){ rotateL(0, 90), L1 }, x, y");
console.log(ast);
console.log(errors);

Integrating combo-script with player app

Although we have combo-player already, you can create your own player easily by implementing ActionPlayer interface.

import { compile, Action, ActionTextGroup, ActionContext, ActionPlayer, ButtonName, StickName } from 'combo-script';

const code = "(a, b) { rotateL(90, 180), up, down }, x, y, (left, a)"
const { ast, errors } = compile(code);
if(errors.length > 0){
  console.error(errors);
  return;
}
// Implement your own ActionPlayer interface.
class MyActionPlayer implements ActionPlayer {
   visitPush(target: ButtonName, context: ActionContext): Promise<any> {
      console.log(`visitPush(${target})`);
      return Promise.resolve();
   },
   // ... full fill other interface functions here ...
}

// And pass your own ActionPlayer to ast.
ast.acceptActionPlayer(new MyActionPlayer());

Implementing plugin function

Functions that are not pre-defined are treated as plugin function.

By using plugin function, you can extend language in your own way.

To use plugin, you should implement your own behaviour in visitPlugin and visitPluginHoldStart and visitPluginHoldEnd in ActionPlayer interface.

import { ActionPlayer, Action, ActionContext } from 'combo-script';

class MyActionPlayer implements ActionPlayer {
   visitPushDown(action: Action, context: ActionContext): Promise<any>{
      reutrn Promise.resolve();
   }
   // ...
   // <full fill other interfaces>
   // ...
   // called in normal sequence.   
   visitPlugin(name: string, args: string[], context: ActionContext): Promise<any> {
      console.log(`plugin:${name}`);
      return Promise.resolve();
   }
   // called when holding action is started.
   visitPluginHoldStart(name: string, args: string[], context: ActionContext): Promise<any> {
      console.log(`plugin:${name}(hold start)`);
      return Promise.resolve();
   }
   // called when holding action is finished.
   visitPluginHoldEnd(name: string, args: string[], context: ActionContext): Promise<any> {
      console.log(`plugin:${name}(hold end)`);
      return Promise.resolve();
   }
}

License

MIT