Skip to content

markwpearce/brighterscript-game-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

404 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BrighterScript Game Engine

Validate Unit Tests Docs License: MIT

An object-oriented game engine and 2D/3D drawing library for Roku, written in BrighterScript.

Build a full game with entities, rooms, collisions, input, and UI - or just pull in the renderer to draw sprites, shapes, billboards, and wireframe/solid 3D models on top of your own Roku app. Same engine, use as much or as little of it as you need.

A red rocket ship flying through a starry blue nebula, dodging gray asteroids, with a score of 5 shown at the top

Asteroids example - 2D movement, collisions, and scoring

A rotating 3D cube textured with the Roku logo on a black background, with on-screen controls for rotation, camera movement, and draw mode

3D example - loading and rendering .stl 3D models with the pseudo-3D renderer

A classic Snake game: a green snake made of square segments turning a corner toward a red apple, on a black grid with a white border

Snake example - grid-based movement and a growing collision shape

Why BrighterScript Game Engine?

  • Object-oriented, like the engines you already know. GameEntity, Room, and lifecycle hooks (onCreate, onUpdate, onCollision, onDrawBegin/onDrawEnd, ...) give you the same shape as Phaser, HaxeFlixel, GameMaker, or Unity - minus the visual editor.
  • A real 2D/3D renderer, not just sprite blitting. Draw images, sprites, animations, shapes, text, and billboards, or render actual 3D models (loaded from .stl) with wireframe, solid, and shaded draw modes - all built on Roku's roCompositor/Draw2D, so it runs on real hardware.
  • Built-in collisions, input, UI, and debug tooling. Circle/rectangle colliders, a retained-mode UI widget tree, and debug overlays (FPS, colliders, memory, GC stats) come standard, so you're not rebuilding the basics for every project.
  • Use only what you need. The Renderer/Canvas layer works standalone if you just want a capable drawing library for an existing Roku app, without adopting the full game loop.
  • Develop without a physical Roku. This engine supports running under the BrightScript Simulator, Marcelo Lv Cabral's desktop BrightScript simulator, so you can iterate on your game without deploying to hardware every time.

A quick taste

sub main()
  game = new BGE.Game(1280, 720)
  game.fitCanvasToScreen()
  game.loadBitmap("player", "pkg:/sprites/player.png")

  room = new MainRoom(game)
  game.defineRoom(room)
  game.changeRoom(room.name)

  game.play()
end sub
class MainRoom extends BGE.Room

  sub new(game as BGE.Game)
    super(game)
    m.name = "MainRoom"
  end sub

  override sub onCreate(args as roAssociativeArray)
    m.game.addEntity(new Player(m.game))
  end sub

end class
class Player extends BGE.GameEntity

  sub new(game as BGE.Game)
    super(game)
    m.name = "Player"
  end sub

  override sub onCreate(args as roAssociativeArray)
    m.position = m.game.canvas.renderer.getCanvasCenter()
    bitmap = m.game.getBitmap("player")
    region = CreateObject("roRegion", bitmap, 0, 0, bitmap.GetWidth(), bitmap.GetHeight())
    m.addImage("sprite", region)
    m.addCircleCollider("body", bitmap.GetWidth() / 2)
  end sub

  override sub onInput(input as BGE.GameInput)
    m.velocity.x = input.x * 10
    m.velocity.y = input.y * 10
  end sub

  override sub onCollision(myCollider as BGE.Collider, otherCollider as BGE.Collider, otherEntity as BGE.GameEntity)
    m.game.postGameEvent("player_hit", {by: otherEntity})
  end sub

end class

This exact code lives in examples/quickstart as a runnable app. See the Documentation for the full API, and the examples below for complete, runnable projects.

Examples

The examples/ directory has full Roku channels you can build and run:

Example What it shows
quickstart The minimal MainRoom/Player example from above, as a runnable app
asteroids A complete 2D game - player movement, bullets, collisions, particle-style explosions, sound
pong Classic 2D Pong, playable in both 2D and 3D camera modes
snake Grid-based movement and growing collision shapes, in 2D and 3D
3d Loading and rendering .stl 3D models with the pseudo-3D renderer
pixels A tour of drawables - polygons, rectangles, sprites, and more, one room per shape
canvas Using the engine's canvas/renderer as a standalone drawing surface
hybrid Mixing this engine's Draw2D-based rendering with a SceneGraph app
rendererTest A manual test harness used while developing the renderer itself

Scaffold a new example (manifest, icons/splash, package.json, a minimal MainRoom) with:

npm run create-example -- <name> ["Display Title"]

Cloning and Running Examples

The BrighterScript Game Engine public repository is on Github

Clone the project:

git clone https://github.com/markwpearce/brighterscript-game-engine.git

This project includes various example Roku apps in the examples directory. To run them, you will need a Roku and have it set up properly for doing development. See: https://developer.roku.com/en-ca/docs/developer-program/getting-started/developer-setup.md.

To run the examples:

Install dependencies:

cd brighterscript-game-engine
npm install

You will need to set up each project in the examples directories. You can do this by using this script:

npm run prepare-examples

Build from the command line:

You can manually build the examples from the command line and manually add the zip files to your Roku:

npm run build-examples

The above command will generate example .zip files like ./examples/asteroids/out/bge-asteroids.zip

Open the Workspace in VS Code:

We recommend you install the great Brightscript Language VSCode Extension.

Create/edit a .env file to specify the details for you target Roku device:

ROKU_USERNAME=<roku development username - default is rokudev>
ROKU_PASSWORD=<roku development password>
ROKU_HOST=<local IP address of the target roku>

Then simply run one of the Debug configurations from the Debug tab.

Installation

Add it as a dependency and install with ropm:

npm install brighterscript-game-engine
ropm install

By default, ropm renames every package's namespace to avoid collisions - so without any extra config, you'd need to reference the engine through its installed name, e.g. new brighterscriptgameengine.BGE.Game(...).

To use the engine directly as BGE.* (as shown throughout this README and the examples), add ropm.noprefix for it to your own project's package.json - this is a per-consumer opt-out, safe to use because BGE is this engine's own deliberate top-level namespace, not an auto-generated one:

{
  "ropm": {
    "noprefix": ["brighterscript-game-engine"]
  }
}

Also add the standard roku_modules diagnostic filter to your bsconfig.json - this is a normal, expected pattern for any project consuming ropm dependencies (this engine's own bsconfig.base.json does the same for its rodash dependency), and avoids noise from a couple of known upstream ropm/brighterscript typedef-validation issues (rokucommunity/ropm#148, rokucommunity/brighterscript#1757):

{
  "diagnosticFilters": [
    { "files": "**/roku_modules/**" }
  ]
}

Known limitation: subclassing BGE.Room/BGE.GameEntity

Subclassing one of the engine's own classes and passing an instance back into an engine method (e.g. game.defineRoom(new MainRoom(game)), or calling super(game) in your subclass's constructor) currently trips a real upstream brighterscript bug (rokucommunity/brighterscript#1758): the generated type declarations reference the class's internal compiled name instead of its real type, so bsc --validate reports an argument-type-mismatch for this - completely ordinary and expected - pattern. The roku_modules filter above doesn't cover this, since the error is reported against your own file, not a roku_modules one.

This is a static type-checker false positive only - type annotations aren't enforced at runtime, so your game still runs correctly regardless. If your own CI gates on bsc --validate reporting zero errors, you'll need to account for this until it's fixed upstream.

Documentation

Documentation can be found here

Acknowledgements

This project was originally forked from Roku-gameEngine by Austin Sojka, and converted into BrighterScript. This work owes a lot to this original project!

Thanks also to:

Releases

Packages

Contributors

Languages