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

@qgml/cli

v1.0.4

Published

Quick Game Markup Language

Downloads

26

Readme

Quick Game Markup Language

QGML is a tool that allows you to structure your game with an HTML-like language and script it using JavaScript.

What it is

a quick way to prototype little web games

What it isn't

a fully-fledged game engine meant for polished games

Installation

$ npm i -g @qgml/cli

CLI Quick Start

Compilation

$ qgml --source myFile

Serve

$ qgml --source myFile --serve 8000

This will serve the compiled game at localhost:8000

note: serving also provides hot-reloading, so, if you modify the qgml file it should automatically reload and apply the changes in your web browser

note2: if you edit an asset (sprite or spritesheet) you have to run qgml again, it won't hot-reload it

For a full list of commands use

$ qgml --help

Quick Start

<qgml
	width = 300
	height = 300
>
	<world default>
		<actor
			id = "my-rect"
			state = ({
				position: { x: 20, y: 20 },
				size: { width: 50, height: 50 },
				color: 'blue'
			})
		/>
	</world>
</qgml>

pro tip: you can save qgml files as .html so that you get syntax highlighting in your favourite code editor!

Tags

QGML

<qgml></qgml>

Think of this as the root element; all other tags are children of it. It contains the configuration for the canvas

Props

| prop | data type | description | | ------------- | --------- | ------------------------------------------------------------ | | width | number | the width of the canvas (default: 300) | | height | number | the height of the canvas (default: 300) | | rootElementID | string | the id of the HTML element in your web page that the canvas should be appended to (default: 'qgml-game') | | debug | boolean | if this prop is present, the game will show the fps, frame-time, and number of actors in the top left |

World

<world></world>

Worlds are basically screens or scenes in your game; an example of worlds would be menu, level1, level2

Props

| props | data type | description | | ------- | --------- | ------------------------------------------------------------ | | id | string | the id of the world; this will be used in scripting to switch between worlds | | default | boolean | if this prop is present the world will be the one loaded as soon as the game starts. If your game has a menu screen, that one would be the default world |

Actor

<actor/>

An actor is anything that appears on the screen: the player, the ground, an object, etc

actor is a self closing tag because it cannot contain anything itself.

Props

| prop | data type | description | | -------- | --------- | ------------------------------------------------------------ | | id | string | the id of the player; this is useful if you want to do anything in script to this actor | | state | object | a state object | | sprite | string | the path relative to the qgml file to an image file | | animator | object | an animator object | | setup | function | a function that is called once when the world is loaded | | update | function | a function that is called every frame | | class | string | the class of the actor |

Animator

The animator overrides the sprite prop. This is used to add animations to certain actors

| property | data type | description | | ------------ | --------- | ----------------------- | | spritesheets | object | the spritesheets object |

Spritesheets
spritesheets: {
    idle: {
        frames: ['path/to/frame0', 'path/to/frame/1', etc],
        frameTime: 10
    },
    //or
    run: {
        strip: 'path/to/animation/strip.png',
        frames: 8,
        frameTime: 10
    },
    etc
}

frames - an array containing the relative paths to frames (images) or the number of frames in a strip

frameTime - the number of game ticks (frames) each animation frame should stay on screen [1 - change each frame (fastest), 10 - change every 10 frames, etc]

strip - the path to an animation strip

example of an animation strip (credit):

Example
<actor
	id = "player"
	state = ({...})
	animator = ({
		spritesheets: {
			idle: {
				strip: './assets/noBKG_KnightIdle_strip.png',
				frames: 15,
				frameTime: 10
			}
		}
	})
/>

[!] Note about setup and update

If the function you pass to setup or update uses classic notation (function () { ... }), the context within it (this) will be the actor itself; so, you will be able to write this.state.position which will return the actor's position, or this.animator which will return the actor's animator.

If the function you pass uses arrow notation (() => { ... }), the context (this) will be the QGML context.

TLDR: it is recommended that you use classic notation for functions passed to setup and update

example:

<actor
	update = (function () {
		console.log (this.state); // will log the actor's state
	})
/>

while

<actor
	update = (() => {
		console.log (this.state); // undefined
	})
/>

Group

<group>{children}</group>

Groups can be used to group together multiple Actors or Groups so that they can move all at once.

Props

| prop | data type | description | | ------ | --------- | ------------------------------------------------------------ | | id | string | just like the id of an actor, this can be used to access this group in a script | | state | object | a state object | | setup | function | a function that is called once when the world is loaded | | update | function | a function that is called every frame |

Modifying a group's position will move all of its children accordingly

<group id = "player">
	<actor id = "player-body"/>
	<group id = "nested" >
		<actor/>
	</group>
</group>

[!] Note about setup and update - everything said about applies

Var (Variables)

<var name = value />

Variables declared in a certain World are only accessible in that world, while variables declared outside of all worlds are considered global and can be accessed and modified from any world.

A single var tag can be used to declare multiple variables, for example

<var
	score = 0
	playerPosition = {
		x: 0,
		y: 0
	}
	playerName = "base name"
/>

Text

<text>text to display</text>

It is used to display text on the canvas

| prop | data type | description | | ----- | --------- | ------------------------------------------------------------ | | state | object | a state object | | font | string | the name of a web-safe font or the name of a font that you're already loading on your web page |

You can use placeholders inside of it to display the values of variables

<text state = { position: { x: 50, y: 100 } }>
	hello! your position is ${playerPosition.x} , ${playerPosition.y}
	and your score is ${score}
</text>

State Objects

| property | data type | description | applies to | | -------- | ---------------------------------------- | ---------------------- | ------------------ | | position | Object { x : Number, y : Number} | the initial position | actor, group, text | | size | Object { width: Number, height: Number } | the initial actor size | actor | | size | Number | the font size | text | | color | String | the fill color | actor, text | | stroke | Object { weight: Number, color: String } | the stroke / outline | actor, text | | style | String | the style of the text | text | | align | String | the text alignment | text |

color

any of the following formats are okay:

  • "rgb(255, 125, 60)"
  • "rgba(0, 25, 125, 0.5)"
  • "rgba(0,0,0,0)"
  • "red", "blue", "lightblue", etc.
  • if color is omitted or set to false the rectangle will be transparent

style

  • "normal"
  • "bold"
  • "italic"
  • "bolditalic"

align

  • "right"
  • "center"
  • "left"

Keymapper

<keymapper/>

The keymapper is used to bind functions to certain keyboard events. Keymappers are specific to the world they are declared inside.

Each prop has the following structure: <key or group of keys>|<event> = (<function>)

key:

  • literal value of the key (w, a, s, d, etc)
  • keycode of the key (32, 87, etc)
  • one of the following special keys: backspace, delete, enter, return, tab, escape, shift, control, option, alt, up_arrow, down_arrow, left_arrow, right_arrow, space

group of keys

it's represented as [<key>,<key>,<key>,...]

event - for keys

  • down - will fire every frame while the key is held down

  • up - will fire every frame while the key is not held down

  • pressed - will fire once when the key is pressed [DEFAULT]

  • released - will fire once when the key is released

event - for groups of keys

  • down - will fire every frame while all the keys are held down

  • up - will fire every frame while none of the keys are held down

  • pressed - will fire once after each key has been pressed at least once

  • released - will fire once after every key has been released

example:

<keymapper
	a|down = (() => {
		console.log ('this will fire every frame while the A key is down');
	})
    
	space|pressed = (() => {
		console.log ('this will fire every time space is pressed');
	})
    
	16|released = (() => {
		console.log ('16 is the keycode for shift so this will fire everytime shift is released');
	})
    
	[q,e]|up = (() => {
		console.log ('this will fire every frame while Q and E are both up');
	})
/>

Script

<script></script>

Scripts are used to add JavaScript code that is executed either in setup (once, when the world is loaded) or in update (every frame)

Scripts are specific to the world they are declared in.

<script setup>
	console.log ('this is executed once when the world is loaded');
</script>
<script update>
	console.log ('this is executed every frame');
</script>

Actor-Template

<actor-template/>

Templates are used to spawn actors of the same type programmatically (from scripts and such).

An example of an actor template would be:

<actor-template
	id = "zombie"
	sprite = "./assets/zombie.png"
	update = (function () {
		// zombie behaviour            
	})
/>

Which you can then instantiate inside <script> tags or inside other actors' setup and update

spawn ('zombie', {
	position: {
		x: 10,
		y: 20
	}, size: {
		width: 40,
		height: 70
	}
});

You can check out the spawn function in the API section below.

Text-Template

<text-template>text</text-template>

Just like actor templates, text templates are used to spawn text objects programmatically.

API

Actors

getActor (id: String) - returns the actor with the specified ID

getActorsByClass (class: String) - returns an array of actors with the specified class

<Actor>.state - returns the state of the actor - this is read-only, the state is not meant to be modified

<Actor>.direction - returns the direction that actor is facing on both axis

<Actor>.getPosition () - returns the actor's position

<Actor>.direction.set (axis: String, value: String || Number)

  • axis can be either 'horizontal' or 'vertical'
  • value can be:
    • 'left' or -1 - for axis == 'horizontal'
    • 'right' or 1 - for axis == 'horizontal'
    • 'up' or 1 - for axis == 'vertical'
    • 'down' or -1 - for axis == 'vertical'

<Actor>.flip.horizontal () - flips the direction horizontally

<Actor>.flip.vertical () - flips the direction vertically

<Actor>.animator - returns the animator of an actor

overlaps (a1: Actor, a2: Actor) - returns true if the actors overlap

spawn (actorTemplateID: String, initialState: stateObject) - spawns a new actor from a specified actor-template, assigns its state to the initial state object, and assigns its class to the template id; it returns the new actor, or null if the specified template id does not exist.

Animator

<Animator>.set (animation: String) - sets the animator's animation to the specified one (ex: 'idle', 'run' - depending on how you declared the animator)

<Animator>.play (animation: String[, onAnimationDone: Function]) - plays the specified animation once, then calls the callback function if one is passed

Group

getGroup (id: String) - returns the group with the specified ID

<Group>.state - returns the state of the group - this is read-only, the state is not meant to be modified

<Group>.getPosition () - returns the position of the group

Entity

Entity = either Actor or Group

dist (x1: Number, y1: Number, x2: Number, y2: Number) - returns the distance between the points (x1, y1) and (x2, y2)

dist (e1: Entity, e2: Entity) - returns the distance between the two entities' positions

getPosition (e: Entity) - returns the entity's position