Burn is a free and open source framework that allows you to create 8-bit flavored application(.nes) using Ruby DSL.
scene do
label "Hello, World!"
end
Just like Recipe and Cookbook are DSL for Chef rubygem, this dead simple DSL is for Burn rubygem, and we call it Fuel. Burning this Fuel will produce this.
Here is another example. With Fuel DSL, you can even compose background music in seconds.
scene do
label "Hello, World!"
play "openning"
end
music "openning" do
tempo :allegro
channel "piano" do
segno
g :dotted
g :eighth, :staccato
a :dotted
a :eighth, :staccato
dal_segno
end
end
Check the output from this.
Would you like to design retro 8-bit graphics? Here you go.
declare do
star <<-EOH
11
11
1111
1111
1111111111111111
11111111111111
111111111111
1111111111
11111111
11111111
11111111
1111 1111
11 11
1 1
EOH
end
scene do
main_loop <<-EOH
star.x=20
star.y-=3
sprite "star"
EOH
end
Please visit our project page for more example.
Creating 8-bit flavored application mean neither outdated nor cheap, but good fit to rapid prototyping. It could be one of best options for education purpose as well.
Moreover, the executables built with burn will work at almost any OS. That said, consequently, burn is a multi-platform programming environment.
Internally, burn contains cc65 executables inside its gemfile and calls them to compile. Main workflow is as follows.
- translate ruby DSL file into c source code
- compile them to make executable(*.nes) by calling cc65
- provide emulator(JSNES) for rapid application development
- Ruby1.9.1+
- gcc(for windows user this is not required)
sudo gem install burn
sudo burn init
burn -p
command use Firefox primarily. If you'd like to use chrome, type burn -p -c
instead.
echo "scene {label 'hello world'}" > main.rb
burn -p
ls tmp/burn/ | grep main.nes
Customize example/shooting/main.rb and play with it if you please.
git clone https://github.com/remore/burn.git
cd burn/example/shooting
burn -p -c
# if you'd like to make executable, simply remove -p option or type burn make
burn
burn make
# you can boot the emulator up whenever you want(without burning Fuel DSL)
burn play
Currently following 4 resources are available. Let's take a quick look how we can make 8-bit flavored application without hassle.
Scene resource is a key concept to make any kind of application. This is where you design screen transition, controller event binding and game balance design etc etc..
The label method can be used in a scene to display static string.
- string String
- Static string to display.
- x Number
- The horizontal coordinate to display, between 0 and 31.
- y Number
- The vertical coordinate to display, between 0 and 28.
scene do
label "Hello, World!"
label "Hello, World!", 4, 5
end
These methods can be used in a scene to fade in or out.
scene do
label "Hello"
fade_in
main_loop
fade_out
goto "next"
end
The play method can be used in a scene to play music.
- song_title String
- Song title to play.
scene do
play "battle"
stop
end
music "battle" do
channel "string" do
g :dotted
g :eighth
c :half
end
end
The stop method can be used in a scene to stop music.
scene do
stop "battle"
end
The color method can be used in a scene to pick a color and set it to specific palette.
- palette Symbol
- Palette to set.
Palette Symbol Description :bg Background color :text Foreground color :palette_x1, :palette_x2, :palette_x3 Colors for :palette_x :palette_y1, :palette_y2, :palette_y3 Colors for :palette_y :palette_z1, :palette_z2, :palette_z3 Colors for :palette_z :sprite Sprite color - color Symbol
- Color to set. Available color pattern is shown below.
Color Symbol :white :lightblue :blue :purple :pink :red :deepred :orange :lightorange :darkgreen :green :lightgreen :bluegreen :gray :black - lightness Symbol
- Lightness of the color to set. `:darkest`, `:darker`, `:lighter` and `:lightest` can be set.
scene do
label "Hello, World!"
color :text, :green, :lighter
end
The wait method can be used in a scene to pause for certain period of time.
- interval Fixnum
- Period of time to pause.
scene do
label "foobar"
fade_out
wait 100
goto "somewhere"
end
The goto method can be used in a scene to jump the scene specified.
- scene_name String
- Destination to jump.
scene "first" do
label "good morning"
goto "second"
end
scene "second" do
label "hi there"
end
The inline method can be used in a scene to inject c source code manually to compile with cc65. Should be used for debugging purpose.
- code String
- C code to inject.
scene do
inline "x=1+2;"
end
The screen method can be used to inflate map data to a scene.
- map String
- Map data consists of hash keys of pattern design.
- vars Hash
- A list of pattern designs.
scene do
screen <<-EOH, { A:"tile", B:"wave", C:"mountain"}
AAAA AA AAA AAA AA A
AA A AA AA AA AA AA AA A
AA A AA AA AA AA AAA
AAAAA AA AA AA AA AA
AA A AA AAAAAAA AA AAA
AA A AA AA AA AA AA AA A
AAAA AAAA AA AA AAA AA A
BB BB BB BBB BBBBB
BB BB BB BB BB BB BB
BB BB BB BB BB BB BB BB
BB BB BB BB BBBBBBB BBBB
BB BB BB BB BB BB
BB BB BB BB BB BB
EOH
end
The sound method in a scene can be used to play sound effect.
- effect_name String
- Name of sound effect to play.
scene do
sound "dead"
end
sound "dead" do
effect do
velocity 15
length 5
pitch 200
end
end
The paint method in a scene can be used to associate color palette with pattern designs inflated on the screen. Typically #paint is called along with #color and #screen method.
- dest Range
- Return value of #range(x_from, y_from, x_to, y_to) is expected. x_from and x_to takes the number between 0 and 255 while y_from and y_to takes the value between 0 and 239.
- palette Symbol
- Palette symbol to apply. Kindly refer candidate symbols listed at color section.
scene "title" do
color :palette_x1, :deepred, :darker
paint range("44px", "5px", "120px", "3px"), :palette_x # range takes String parameter
color :palette_y2, :pink, :darkest
paint range(30, 2, 30, 12), :palette_y # range method can take Number as well. In this case x_from and x_to takes the value between 0 and 31, while y_from and y_to takes the value from 0 and 29.
end
The main_loop method in a scene can be used to repeat a block of code. More detail can be found at .rrb section.
- rrb_source String
- Source code written in .rrb(Resticted Ruby) syntax.
scene "title" do
color :palette_x1, :deepred, :darker
paint range("44px", "5px", "120px", "3px"), :palette_x # range takes String parameter
color :palette_y2, :pink, :darkest
paint range(30, 2, 30, 12), :palette_y # range method can take Number as well. In this case x_from and x_to takes the value between 0 and 31, while y_from and y_to takes the value from 0 and 29.
end
Declare resource is essential part of programming with using Scene#main_loop.
If you give Number as shown below, then method name like #frame or #color_flag becomes variable in Scene#main_loop process.
declare do
frame 0
color_flag 0
end
If you give String conststs of 8x8 character block just like following example code, then left left-hand member becomes sprite object in Scene#main_loop process.
declare do
tile <<-EOH
11111111
11222211
11233211
11233211
11233211
11233211
11222211
11111111
EOH
end
This is where burn rubygem compose music for you. The only requirement for you to start to compose music is your favorite text editor.
Music resource can accept only two methods so far, #tempo and #channel.
The tempo method in a music can be used to set a tempo of a song.
- speed Symbol
- song speed symbol to set.
Song Speed :presto :allegro :moderato :andante :adagio :largo
music "fanfare" do
tempo :allegro
channel ...
end
The channel method in a music can be used to set a channel of the song. Maximum three channels per music can be set.
- instrument String
- instrument to play.
Instrument "bass" "piano" "string" "arpeggio" "step" "bell" "acoustic" "guitar" "theremin"
Notes of the music are described as shown below.
- Total 61 notes(5 octaves + rest) notes are available.
- For instance, available methods are,
#c0
(0 stands for octave),#ds0
(s stands for flat),#d0
,#es0
...
- For instance, available methods are,
#segno
and#dal_segno
are available too- This way you can repeat song
- Each note can take length as their parameter. Here is list of length available
:sixteenth
,:eighth
,:quarter
,:half
:dotted_sixteenth
,:dotted_eighth
,:dotted_quarter
,:dotted_half
:triplet_sixteenth
,:triplet_eighth
,:triplet_quarter
,:triplet_half
- Each note can take expression parameter as well
:tenuto
:accent
:staccato
With these basic understanding how you can compose song, here is an example of music.
music "sarabande" do
tempo :allegro
channel "string" do
segno
d2 :eighth
rest :eighth
e2 :eighth
rest :eighth
dal_segno
end
channel "piano" do
segno
a3 :dotted_eighth
rest :sixteenth
g3 :triplet_eighth
g3 :triplet_eighth
g3 :triplet_eighth
dal_segno
end
end
Sound resource can accept only #effect method as of now. Available methods for #effect are shown below.
with this block, you can call following method to configure sound setting.
The duty_cycle method in a sound can be used to set duty cycle type.
- duty_cycle(ratio)
- duty cycle symbol to set. It takes :higher by default.
Duty Cycle Type Value :lowest 12.5% :lower 25% :higher 50% :highest 75% - velocity(level)
- Volume level number of the sound, between 0 and 15. It takes 7 by default.
- envelope_decay(flag), envelope_decay_loop(flag), length_counter_clock(flag)
- It takes either :enable or :disable flag symbol. Disabled by default.
- length(size)
- Length number of the sound effect, between 1 and 254. It takes 16 by default.
- pitch(control)
- Control number of the sound effect, between 0 and 254. (This value is stil uncontrollable so far. Need to improve)
sound "attack" do
effect do
duty_cycle
velocity 15
envelope_decay :disable
length 10
pitch 200
envelope_decay_loop :disable
length_counter_clock :disable
end
end
TBD(articles about #show, #sprite, #rand and #is_pressed are coming very soon)
- Shiru - this project had never been born if I had not found this article
- My friend from high school - I appreciate him for sending me fine-grained review as always
GPLv3
- New VM Support
- compatiblize with enchant.js
- Enhancement of Fuel DSL
- for Screen, support screen scroll and simple sprite
- for Screen, adding .bmp and .png support to make designing pattern table easier
- for Sound, add triangle wave and noise effect
- for Music, add custom instrument DSL
- for Declare, support string and boolean declaration(currently only number and pattern table is supported)
- Improvement of Internal Architecture
- make cc65 alternative in Ruby
- Other Feature To Be Supported
- make burn rubygem work with mruby(not soon)
- Fix bugs
- declaring 2x2 pattern works, however 2x1 pattern doesn't