0.0
The project is in a healthy, maintained state
A mountable Rack endpoint that serves a DragonRuby GTK HTML5 export with the cross-origin isolation headers its WASM runtime needs, and rebases the bundle's relative asset links so it works under any mount path. Ships an optional Rails generator and rake task; the Rack app itself needs no Rails.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 2.2, < 4
 Project Readme

dragonruby-rack

Serve a DragonRuby GTK HTML5 export from a Rack or Rails app, on your own domain, without an iframe and without itch.io.

# Gemfile
gem "dragonruby-rack"

# config/routes.rb
mount DragonRuby::Rack::Game.new(Rails.root.join("games/underwater")) => "/underwater"

That is the whole thing. The game is then at /underwater/.

Built for and running on stammer.dev/underwater.

Why this is not just a static directory

DragonRuby's WASM runtime allocates a SharedArrayBuffer, and browsers hand that out only to a cross-origin isolated document — one served with both

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Rails' static file server runs before the router and cannot set headers per path, so a bundle dropped into public/ is served without them and the game never boots. Hence: keep the bundle outside public/, serve it through this endpoint, which sets the headers on the document and on every subresourcerequire-corp applies to the .wasm too.

The second thing it does is less obvious. The export links its assets relatively (game.css, gamedata/…), which under a mount only resolve if the document URL ends in a slash — and nothing can guarantee that, since Rails normalizes the path away before the endpoint sees it and a redirect onto the slash would be a loop. So the endpoint injects a <base href="/underwater/"> into the served HTML, and the assets resolve either way.

Without Rails

It is a plain Rack app; Rails is not a dependency.

# config.ru
require "dragonruby-rack"
run DragonRuby::Rack::Game.new("builds/underwater-html5")

or mounted:

require "dragonruby-rack"

app = Rack::Builder.new do
  map("/underwater") { run DragonRuby::Rack::Game.new("builds/underwater-html5") }
end

Getting a bundle in

Export the game (dragonruby-publish --platforms=html5 --package …) and unpack the zip where the mount points:

rake dragonruby:install[../underwater/builds/underwater-html5.zip,underwater]

The task replaces the directory rather than unpacking over it — a file that existed in the old version and not in the new one would otherwise stay behind and be served for good. Because that is a delete, it refuses any destination that is not empty and holds no index.html, and it checks afterwards that what came out has an index.html and a .wasm in it (a desktop export unzips perfectly well and then serves nothing). FORCE=1 overrides the refusal.

config.dragonruby.games_root sets where bundles live; the default is games.

Generator

rails g dragonruby:mount underwater

Creates games/underwater/ and writes the mount into config/routes.rb. --path= and --at= override the directory and the URL. Running it twice does not mount the path twice.

What this gem is not

It does not contain DragonRuby, and it does not build your game. DragonRuby is commercial software with its own licence; you need your own copy to produce the export this serves. This gem only takes the finished directory and puts it on the web correctly.

Development

bundle install
bundle exec rspec

Licence

MIT. See LICENSE.txt.