Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
builddir/
runtime/
shaderc
rayjs
Expand Down
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

Add your changes after this line, example:

`## [MAJOR.MINOR.REVISION-STABILITY] - DD.MM.YYYY`

## [1.0.1-dev] - 17.03.2024

### Added

- Changes specifier in [CHANGELOG.md](./CHANGELOG.md)
- Version specifier in [VERSION](./VERSION)
- Node version specifier in [.nvmrc](./bindings/.nvmrc) to allow compatibility
- Simple shell script to invoke the bindings generator in [`generate-bindings.sh`](./generate-bindings.sh)
- Simple shell script to invoke the build process in one step in [`build-rayjs.sh`](./build-rayjs.sh)

### Changed

- Upgraded raylib to [9a8d73e](https://github.com/raysan5/raylib/commit/9a8d73e6c32514275a0ba53fe528bcb7c2693e27)
- Upgraded raygui to [82ba2b1](https://github.com/raysan5/raygui/commit/82ba2b1a783208d6a1f80d8977d796635260c161)
- Upgraded quickjs to [6a89d7c](https://github.com/bellard/quickjs/commit/6a89d7c27099be84e5312a7ec73205d6a7abe1b4)
- Generated new bindings
- Upgraded all packages of the bindings generator

### Removed

- Removed the need of transpilation when using the bindings generator (this is useful to debug generator issues as ts-node can represent errors as they are, without the need of source maps)
- Removed webpack requirement

### Fixed

- Markdown linting errors
18 changes: 12 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ IF (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
ENDIF()
if (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DCONFIG_BIGNUM")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -DCONFIG_BIGNUM")
endif (UNIX)

project(rayjs)

Expand All @@ -17,14 +21,16 @@ message("=== Configure QuickJS ===")
set(quickjs_version 2021-03-27)
set(quickjs_sources_root ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/quickjs)
set(quickjs_sources
${quickjs_sources_root}/quickjs.h
#${quickjs_sources_root}/quickjs-libc.h
${quickjs_sources_root}/quickjs.c
${quickjs_sources_root}/cutils.c
${quickjs_sources_root}/cutils.h
${quickjs_sources_root}/libbf.c
${quickjs_sources_root}/libbf.h
${quickjs_sources_root}/libregexp.c
${quickjs_sources_root}/libregexp.h
${quickjs_sources_root}/libunicode.h
${quickjs_sources_root}/libunicode.c
${quickjs_sources_root}/libbf.c
${quickjs_sources_root}/cutils.c
#${quickjs_sources_root}/quickjs-libc.c
${quickjs_sources_root}/quickjs.h
${quickjs_sources_root}/quickjs.c
)
add_library(quickjs STATIC
${quickjs_sources}
Expand Down
93 changes: 59 additions & 34 deletions readme.md → README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
![rayjs logo](./doc/logo.png)

# rayjs - Javascript + Raylib

QuickJS based Javascript bindings for raylib in a single ~3mb executable

## What is this?

rayjs is small ES2020 compliant Javascript interpreter based on [QuickJS](https://bellard.org/quickjs/) with bindings for [Raylib](https://www.raylib.com/). You can use it to develop desktop games with Javascript.

## What this is not

rayjs is not a binding for NodeJS nor is it running in the browser (yet). It's comes with its own Javascript engine (QuickJS) similar to how NodeJS comes with the V8 engine. That makes it much easier to run and distribute rayjs programs as all you need to run a program / game is the small rayjs executable. No installation, no dlls or additional files are needed.

## Features

* Compiles into a single, small executable without any dependencies for easy distribution
* Use modern Javascript features like classes or async/await
* In-depth auto-complete with definitions for the whole API

## Getting started

1. Download the binary for your platform from the [release section](https://github.com/mode777/rayjs/releases).
2. Unzip the executable to a folder and create a new text file in the same folder. Rename the file to `main.js`
3. Open the file with a text-editor (e.g. Notepad) and add the following code

```javascript
const screenWidth = 800;
const screenHeight = 450;
Expand All @@ -35,11 +42,14 @@ rayjs is not a binding for NodeJS nor is it running in the browser (yet). It's c
}
closeWindow();
```

4. Run the `rayjs` executable
5. Congratulations, you have created your first rayjs app.
5. Congratulations, you have created your first rayjs app.

## Running code
rayjs will run code in three different modes

Rayjs will run code in three different modes

1. If no parameter is given it will look for a file called `main.js` in the executable directory
2. It will run a given Javascript file given as a command line argument like this `rayjs <filename>`
3. It will look for a file called `main.js` in a folder given as a command line argument like this `rayjs <foldername>`
Expand All @@ -50,18 +60,18 @@ The directory of the main Javascript module will also be the working directory o

The following raylib APIs are supported so far (with a few exceptions):

- core (no VR support yet)
- shapes
- textures
- text (no support for GlyphInfo yet)
- models (no animation support)
- shaders
- audio
- raymath
- rcamera
- rlights
- raygui
- reasings
* core (no VR support yet)
* shapes
* textures
* text (no support for GlyphInfo yet)
* models (no animation support)
* shaders
* audio
* raymath
* rcamera
* rlights
* raygui
* reasings

Similar to including a header in C and for your convenience, all types/functions are provided globally. They are additionally available in a module called 'raylib'

Expand All @@ -70,6 +80,7 @@ To check which API functions are not available (yet) check `/bindings/src/index.
## Additional APIs

Rayjs comes with some additional functionality on top of raylib to make writing raylib code with Javascript easier

```typescript
/** Replace material in slot materialIndex (Material is NOT unloaded) */
declare function setModelMaterial(model: Model, materialIndex: number, material: Material): void;
Expand All @@ -92,6 +103,7 @@ Additionally it also comes with bindings to [lightmapper.h](https://github.com/a
## Auto-Complete / Intellisense

rayjs comes with full auto-complete support in the form of the definitions file `lib.raylib.d.ts`. These will work with Typescript and Javascript. In order to use them with Javascript you should create a Typescript configuration file in the project root (even if you are not using Typescript) called `tsconfig.json` with the following configuration

```json
{
"compilerOptions": {
Expand All @@ -103,74 +115,87 @@ rayjs comes with full auto-complete support in the form of the definitions file
}
}
```

After that put the `lib.raylib.d.ts` file in the same folder and optionally restart your IDE. Auto-complete should be working:
![](doc/auto-complete.png)
![Autocomplete example](doc/auto-complete.png)

## Examples

Some official raylib examples were already ported to Javascript and can be found in the `examples` folder.
Some official raylib examples were already ported to Javascript and can be found in the `examples` folder.

Additional examples are described here.

```
```shell
./rayjs examples/js_example_project
```

Barebones example project on how to structure a project that uses Javascript
```

```shell
./rayjs examples/js_mesh_generation.js
```

Shows how to create a mesh from Javascript ArrayBuffers
```

```shell
./rayjs examples/shaders/js_shaders_gradient_lighting.js
```

Creates a gradient and uses it as lighting for a 3d scene
```

```shell
./rayjs examples/ts_dungeon
```

Small example game that uses Typescript with Webpack for transpilation and bundling
```

```shell
./rayjs examples/ts_game
```
Example how to integrate existing JS libraries. This example integrates the Inkjs library to compile and play a game written in the Ink interactive fiction language.

Example how to integrate existing JS libraries. This example integrates the Inkjs library to compile and play a game written in the Ink interactive fiction language.

### Lightmapper usage
Rayjs integrates the [lightmapper.h](https://github.com/ands/lightmapper/tree/master) library to render baked lighting.

Rayjs integrates the [lightmapper.h](https://github.com/ands/lightmapper/tree/master) library to render baked lighting.
The example demonstrates it's usage.
```

```shell
./rayjs examples/js_lightmapper.js
```

Meshes must have unwrapped lightmap uvs in the second UV channel.

![](2023-07-20-13-08-52.png)
![Example lightmap](2023-07-20-13-08-52.png)

The example uses an environment that is uniform white which will lead to baking pure ambient occlusion. To bake other light sources, lower the amount of ambient lighting and everything that is rendered with a color other than black will become an emissive lightsource during baking. Rendering will just work as usual and custom shaders are supported. E.g. while the raylib default shader does not support color intensities greater than 1.0, the lightmapper does support them for higher intensity lighting.

The example will try to bake lighting alongside the render loop which is still buggy and leads to artifacts. Baking before rendering works better.

## Performance
QuickJS is one of the [faster JS interpreters](https://bellard.org/quickjs/bench.html). I'm getting about 13000 bunnys in the unmodified bunnmark before dropping any frames on my 2020 Macbook Air M1 which seems pretty good.
![Bunnymark](doc/bunny.png)

QuickJS is one of the [faster JS interpreters](https://bellard.org/quickjs/bench.html). I'm getting about 13000 bunnies in the unmodified bunnmark before dropping any frames on my 2020 Macbook Air M1 which seems pretty good.
![Bunnymark](doc/bunny.png)

## Building

Here are some basic steps if you want to compile rayjs yourself.
You should use CMake for building. **Please note that QuickJS needs Mingw in order to compile correctly on Windows**

### Check out required files
```bash

```shell
git clone https://github.com/mode777/rayjs.git
git submodule update --init --recursive
```

### Build with cmake

Make sure you have cmake installed and in your path.
```bash

```shell
cd rayjs
mkdir build
cd build
cmake ..
make
./build-rayjs.sh
```


See [`build-rayjs.sh`](./build-rayjs.sh) to understand how to integrate
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.1-dev
1 change: 1 addition & 0 deletions bindings/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
Loading