ifrb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +74 -0
- data/Rakefile +7 -0
- data/bin/ifrb +29 -0
- data/examples/basil.rb +305 -0
- data/lib/ifrb.rb +66 -0
- data/lib/ifrb/version.rb +9 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f165e1c66438091ed255557f44eed72ca9eaf219
|
4
|
+
data.tar.gz: 6f433a81afa77053b2b054b85bc166f42e8496b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d727149c338ec392fb376fba3fdef7ad32202df0506b30852e15e654b27e90cb73146423a0c314ecf0a22e59e2c7feb05d04850e46ed29b82a0a5a4550aba49
|
7
|
+
data.tar.gz: 9941d5b139b9c3e09a4927518de2251b6bbf41459d310cbda65293d8b86797894703beb8bd59ce096995085158256eb46e6e1a70b73778d78a79b726fc292323
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# ifrb
|
2
|
+
|
3
|
+
Interactive fiction (IF), for interactive Ruby (IRB). Play interactive fiction games from within the cozy familiarity of irb! Write stories that incorporate actual, executable Ruby code in the dialog!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
RubyGems is your friend:
|
8
|
+
|
9
|
+
$ gem install ifrb
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Try it with one of the examples:
|
14
|
+
|
15
|
+
$ ifrb basil
|
16
|
+
|
17
|
+
Or, if you want to do it from within IRB directly:
|
18
|
+
|
19
|
+
$ irb
|
20
|
+
irb> require 'ifrb'
|
21
|
+
irb> ifrb "basil"
|
22
|
+
|
23
|
+
## Writing Your Own Adventures
|
24
|
+
|
25
|
+
Just create a new ruby file. You need at least one method, called `start`, which will be called when your adventure loads.
|
26
|
+
|
27
|
+
def start
|
28
|
+
# ...
|
29
|
+
end
|
30
|
+
|
31
|
+
Define methods inside that method to add actions that are available for players. At the very least, you should add a method called `look`, which will be called when the room loads. The `look` method should describe the room:
|
32
|
+
|
33
|
+
def start
|
34
|
+
def look
|
35
|
+
_format <<-DESC
|
36
|
+
You see a big room. Not much else in here.
|
37
|
+
DESC
|
38
|
+
end
|
39
|
+
|
40
|
+
# ...
|
41
|
+
end
|
42
|
+
|
43
|
+
Other rooms are defined as top-level methods:
|
44
|
+
|
45
|
+
def start
|
46
|
+
#...
|
47
|
+
end
|
48
|
+
|
49
|
+
def monster
|
50
|
+
def look
|
51
|
+
_format "Yuck! A monster!"
|
52
|
+
end
|
53
|
+
# ...
|
54
|
+
end
|
55
|
+
|
56
|
+
Transition to rooms using the `_load_room` method:
|
57
|
+
|
58
|
+
def start
|
59
|
+
def north
|
60
|
+
_load_room :monster
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def monster
|
65
|
+
# ...
|
66
|
+
end
|
67
|
+
|
68
|
+
See the examples for more information about writing your own adventures. Good luck!
|
69
|
+
|
70
|
+
## License
|
71
|
+
|
72
|
+
Creative Commons Attribution 4.0 International License -- (c) Jamis Buck <jamis@jamisbuck.org>
|
73
|
+
|
74
|
+
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">IFRB</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="http://github.com/jamis/ifrb" property="cc:attributionName" rel="cc:attributionURL">Jamis Buck</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="http://github.com/jamis/ifrb" rel="dct:source">http://github.com/jamis/ifrb</a>.
|
data/Rakefile
ADDED
data/bin/ifrb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/bin/sh ruby
|
2
|
+
|
3
|
+
require "irb"
|
4
|
+
|
5
|
+
game = ARGV.pop or abort "please specify the game you'd like to play"
|
6
|
+
game = game.gsub(/\.rb$/, "")
|
7
|
+
|
8
|
+
if !File.exists?("#{game}.rb")
|
9
|
+
ex_path = File.join(File.dirname(__FILE__), "..", "examples", game)
|
10
|
+
if File.exists?("#{ex_path}.rb")
|
11
|
+
game = ex_path
|
12
|
+
else
|
13
|
+
abort "no such game `#{game}'"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
old_setup = IRB.method(:setup)
|
18
|
+
IRB.singleton_class.send(:define_method, :setup) do |*args|
|
19
|
+
old_setup.call(*args)
|
20
|
+
old_rc = IRB.conf[:IRB_RC]
|
21
|
+
IRB.conf[:IRB_RC] = ->(context) do
|
22
|
+
old_rc[context] if old_rc
|
23
|
+
command = "ifrb #{game.inspect}\n"
|
24
|
+
command.reverse.chars.each { |c| context.irb.scanner.ungetc(c) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
ARGV.push "-rifrb"
|
29
|
+
IRB.start(__FILE__)
|
data/examples/basil.rb
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
WORDS = %w(wonky insipid squeak babushka cantilever intrepid flipper
|
2
|
+
periwinkle ewok munch gorgonzola ogle)
|
3
|
+
|
4
|
+
def start
|
5
|
+
_format <<-DESC
|
6
|
+
"Confound that blasted..."
|
7
|
+
|
8
|
+
The dust swirles and settles to the gentle swearing of your master, Basil Smockwhitener (wizard and gentleman). Coughing, you push your way through to him, and find him trapped beneath a large fallen beam.
|
9
|
+
|
10
|
+
Try as you might, thought, it's too much for you to lift. Basil appears to be injured, but he shoos you away.
|
11
|
+
|
12
|
+
"Stop, Fabian," he says. "Just--stop. It's too heavy. Go on ahead and find the Magic Doohickie. We can use it to get this beam off me. It's the only way, now. No arguing! Just go!"
|
13
|
+
|
14
|
+
You shrug, recognizing that tone of voice, and resigned as usual. "Yes, sir. I'll see what I can find."
|
15
|
+
|
16
|
+
DESC
|
17
|
+
|
18
|
+
armor = Class.new { def ticklish?; false; end }
|
19
|
+
|
20
|
+
doohickie = Class.new do
|
21
|
+
attr_reader :magic_a, :magic_b, :magic_c
|
22
|
+
|
23
|
+
def initialize(a, b, c)
|
24
|
+
@magic_a = a
|
25
|
+
@magic_b = b
|
26
|
+
@magic_c = c
|
27
|
+
end
|
28
|
+
|
29
|
+
def ==(h)
|
30
|
+
magic_a == h.magic_a &&
|
31
|
+
magic_b == h.magic_b &&
|
32
|
+
magic_c == h.magic_c
|
33
|
+
end
|
34
|
+
|
35
|
+
def dup
|
36
|
+
puts "Yeah, you kinda wish it were that easy, eh?"
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
alias clone dup
|
41
|
+
end
|
42
|
+
|
43
|
+
@__basil_freed = false
|
44
|
+
@__locked = true
|
45
|
+
@__armor = armor.new
|
46
|
+
@__armory_blocked = true
|
47
|
+
@__looted = false
|
48
|
+
@__doohickie = doohickie.new(rand(100), rand(100), rand(100))
|
49
|
+
@__setting_goal = rand(100)+1
|
50
|
+
|
51
|
+
undef start
|
52
|
+
basil
|
53
|
+
end
|
54
|
+
|
55
|
+
def basil
|
56
|
+
def look
|
57
|
+
if @__basil_freed
|
58
|
+
_format <<-DESC
|
59
|
+
Basil is free! You've done it! He's limping a bit, but he insists that it's nothing that a few cookies and a good night's rest won't cure. He gestures anxious to the south. "Let's go, Fabian!"
|
60
|
+
DESC
|
61
|
+
elsif @__looted
|
62
|
+
_format <<-DESC
|
63
|
+
You show Basil the Magic Doohickie and he breathes a sigh of relief. "You've done it, Fabian! Jolly good, old man! Now, just [adjust] the thing to the correct setting and get this beam off me. What? How should I know what the correct setting is? Just experiment. It's something between 1 and 100."
|
64
|
+
DESC
|
65
|
+
else
|
66
|
+
_format <<-DESC
|
67
|
+
What was formerly the ceiling now lies mostly on the floor, much of it unfortunately on your master, Basil. He gestures angrily at you to get moving. "Find the Doohickie!"
|
68
|
+
|
69
|
+
The passage goes south (to the exit), and north (towards the treasure chamber). Presumably, Basil wants you to go north.
|
70
|
+
DESC
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def adjust(setting=0)
|
75
|
+
if !@__basil_freed && @__looted
|
76
|
+
if setting < @__setting_goal
|
77
|
+
_format "The doohickie grows cooler momentarily."
|
78
|
+
elsif setting > @__setting_goal
|
79
|
+
_format "The doohickie grows warmer momentarily."
|
80
|
+
else
|
81
|
+
@__basil_freed = true
|
82
|
+
_format <<-DESC
|
83
|
+
With a satisfying *thunk*, the beam that had trapped Basil disappears! He stands up, dusts himself off, and shakes your hand a bit more vigorously than you think the situation calls for. "Well done, man! You did it! Now, let's get out of here. To the south!"
|
84
|
+
DESC
|
85
|
+
end
|
86
|
+
else
|
87
|
+
_format "Adjust what? You're funny."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def south
|
92
|
+
if @__basil_freed
|
93
|
+
_load_room :escape
|
94
|
+
else
|
95
|
+
_format <<-DESC
|
96
|
+
Basil shouts angrily at you. "Not that way, you oaf! North! North! Get the Doohickie!" His mustaches are practically bristling.
|
97
|
+
DESC
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def north
|
102
|
+
if @__basil_freed
|
103
|
+
_format <<-DESC
|
104
|
+
"What are you, a glutton for punishment?" Basil shakes his head in disbelief. "Come along, Fabian. South, man! Let's get out of here."
|
105
|
+
DESC
|
106
|
+
else
|
107
|
+
_load_room :lock
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def lock
|
113
|
+
def look
|
114
|
+
if @__locked
|
115
|
+
_format <<-DESC
|
116
|
+
Not that you have much experience with looting abandoned treasure chambers or anything, but the pattern on the far wall looks a lot like a magical lock. Your hunch is borne out by a large sign above it that reads:
|
117
|
+
|
118
|
+
"This is a magical lock. You'll never figure it out. Only a real magician, one able to [invoke] a spell that takes a string and reverses it, will ever manage to unlock it."
|
119
|
+
|
120
|
+
Better get busy. The alternative is to go south again and tell Basil you failed. (Whew. That gives you chills just thinking about it.)
|
121
|
+
DESC
|
122
|
+
else
|
123
|
+
_format <<-DESC
|
124
|
+
There is a passage going north. This is because you successfully invoked the spell that unlocked it. Good for you! Basil would be so proud. Assuming he noticed.
|
125
|
+
|
126
|
+
Oh, speaking of that. You can also go south, back to Basil.
|
127
|
+
DESC
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def south
|
132
|
+
_load_room :basil
|
133
|
+
end
|
134
|
+
|
135
|
+
def north
|
136
|
+
if @__locked
|
137
|
+
_format <<-DESC
|
138
|
+
What, through a magically locked door? You might try opening it first. Although, you'll need to unlock it before you can open it. Have you tried [invoke] yet?
|
139
|
+
DESC
|
140
|
+
else
|
141
|
+
_load_room :armory
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def invoke(spell=nil, &block)
|
146
|
+
if spell.nil? && !block
|
147
|
+
_format <<-DESC
|
148
|
+
Nothing happens, and it does so in a surprisingly uninspiring way. (Maybe you should provide the spell you want to cast? Perhaps as a lambda, or a block? But I'm just the narrator. What would I know about magic?)
|
149
|
+
DESC
|
150
|
+
elsif spell && !spell.respond_to?(:call)
|
151
|
+
_format "Um. I'm no expert, mind, but that doesn't look like a spell."
|
152
|
+
else
|
153
|
+
spell ||= block
|
154
|
+
words = WORDS.shuffle[0,5]
|
155
|
+
|
156
|
+
_format "Right. Let's see if this cantrip works. I'll just plug in a few words here..."
|
157
|
+
success = words.all? do |word|
|
158
|
+
result = spell[word]
|
159
|
+
puts " - `#{word}' becomes `#{result}'..."
|
160
|
+
word.reverse == result
|
161
|
+
end
|
162
|
+
|
163
|
+
if success
|
164
|
+
@__locked = false
|
165
|
+
_format "What the..?! You did it! A passage opens to the north!"
|
166
|
+
else
|
167
|
+
_format "Hmm. That's not quite right. Maybe you should have another go?"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def armory
|
174
|
+
def look
|
175
|
+
if @__armory_blocked
|
176
|
+
_format <<-DESC
|
177
|
+
The walls of this room are covered with exotic (and ancient-looking) weapons. Suits of armor are arranged haphazardly on stands, with one particularly imposing specimen standing--eerily life-like--right in front a door to the north. On its tabard is written the words:
|
178
|
+
|
179
|
+
"Tickle me. I dare you."
|
180
|
+
|
181
|
+
The only other exit is to the south.
|
182
|
+
DESC
|
183
|
+
else
|
184
|
+
_format <<-DESC
|
185
|
+
Aside from all the weapons and armor arranged around the walls, a large suit of armor lies prone on the floor.
|
186
|
+
|
187
|
+
One passage lies open to the north, and another to the south.
|
188
|
+
DESC
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def south
|
193
|
+
_load_room :lock
|
194
|
+
end
|
195
|
+
|
196
|
+
def north
|
197
|
+
if @__armory_blocked
|
198
|
+
_format <<-DESC
|
199
|
+
You think so, do you? Even with that big suit of armor daring you to tickle it?
|
200
|
+
DESC
|
201
|
+
else
|
202
|
+
_load_room :treasury
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def tickle(what=:armor)
|
207
|
+
if what == :armor
|
208
|
+
if @__armor.ticklish?
|
209
|
+
@__armory_blocked = false
|
210
|
+
|
211
|
+
def tickle(what=:armor)
|
212
|
+
_format "No need for more tickling. The armor is defunct!"
|
213
|
+
end
|
214
|
+
|
215
|
+
_format <<-DESC
|
216
|
+
You boldly start scratching the suit along its sides, viciously making baby noises while watching the suit's arms. Hollowly, from deep within the armor, a tinny-sounding giggling begins. It grows in volume like the Doppler effect with poor AM reception until the suit's arms start flailing helplessly and the armor falls to the floor.
|
217
|
+
|
218
|
+
As you back away, the giggling slowly fades, leaving nothing but rather unsettling echoes.
|
219
|
+
|
220
|
+
The passage to the north is unblocked!
|
221
|
+
DESC
|
222
|
+
else
|
223
|
+
_format <<-DESC
|
224
|
+
You reach out hesitantly and poke the suit of armor about where its belly button ought to be. Feeling faintly ridiculous, you add, "goochie goochie goo."
|
225
|
+
|
226
|
+
One of the suit's arms suddenly holds up a sign that reads, "Sorry. #ticklish? == false," before the other blindsides you and knocks you to the floor. By the time you stand up again, the armor has reset.
|
227
|
+
|
228
|
+
Hmm. Maybe you ought to try to [enhance] the armor with a module that makes it [ticklish?]
|
229
|
+
DESC
|
230
|
+
end
|
231
|
+
else
|
232
|
+
_format "That's a rather odd thing to tickle."
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def enhance(mod)
|
237
|
+
if @__armory_blocked
|
238
|
+
@__armor.extend(mod)
|
239
|
+
_format "Your enhancement settles experimentally onto the armor. Maybe try tickling it now?"
|
240
|
+
else
|
241
|
+
_format "The armor is nonfunctional, now. Enhancing it won't do anything."
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def treasury
|
247
|
+
def look
|
248
|
+
if @__looted
|
249
|
+
_format <<-DESC
|
250
|
+
The fake Magic Doohickie looks pretty convincing there on its pedestal. Perhaps you should go rescue Basil now that yo uhave the real one. Go south!
|
251
|
+
DESC
|
252
|
+
else
|
253
|
+
_format <<-DESC
|
254
|
+
This is it! The treasury, containing the ancient and mysterious Magic Doohickie of Hank Doolickie! Its rumored powers are many, and its rumored guardians are...well...many, also. Somehow, you need to [swap] it with an identical [doohickie], so that the guards won't realize it's been taken.
|
255
|
+
|
256
|
+
Or, you can give up and go south. Quitter.
|
257
|
+
DESC
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def doohickie
|
262
|
+
@__doohickie
|
263
|
+
end
|
264
|
+
|
265
|
+
def south
|
266
|
+
_load_room :armory
|
267
|
+
end
|
268
|
+
|
269
|
+
def swap(a, b)
|
270
|
+
if @__looted
|
271
|
+
_format "Wait, don't do that! You've already pulled off the heist!"
|
272
|
+
elsif a.equal?(b)
|
273
|
+
_format "What are you trying to pull? You can't swap a thing with itself!"
|
274
|
+
else
|
275
|
+
a, b = b, a if b == @__doohickie
|
276
|
+
if a == @__doohickie
|
277
|
+
if a == b
|
278
|
+
@__looted = true
|
279
|
+
@__my_doohickie, @__doohickie = a, b
|
280
|
+
_format <<-DESC
|
281
|
+
Whoa! That was tricky! You totally swapped your fake for the real deal! This means...wait. This means you can go free Basil, now! Quickly, head south!
|
282
|
+
DESC
|
283
|
+
else
|
284
|
+
_format <<-DESC
|
285
|
+
Hmm...those don't quite look equivalent. I suspect something really, really, really, really, really, really, really bad would happen if you actually tried swapping them. Can you make your fake one look anything more like the real [doohickie]?
|
286
|
+
DESC
|
287
|
+
end
|
288
|
+
else
|
289
|
+
_format "That's...odd. Try that again, this time with the [doohickie]."
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def escape
|
296
|
+
def look
|
297
|
+
_format <<-DESC
|
298
|
+
You've done it! You recovered the Magic Doohickie, rescued Basil, and capped it all of with a daring escape. Well, maybe not *daring*. But an escape, nonetheless.
|
299
|
+
|
300
|
+
Well done!
|
301
|
+
DESC
|
302
|
+
|
303
|
+
quit
|
304
|
+
end
|
305
|
+
end
|
data/lib/ifrb.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
if !defined? IRB
|
2
|
+
abort "ifrb will only work within an IRB session"
|
3
|
+
end
|
4
|
+
|
5
|
+
IRB.conf[:PROMPT][:IFRB] = {
|
6
|
+
:PROMPT_I => "%N> ", # "initial" prompt
|
7
|
+
:PROMPT_C => "..", # continued command
|
8
|
+
:PROMPT_S => "..", # continued string
|
9
|
+
:PROMPT_N => "..", # nested command
|
10
|
+
:RETURN => "" # formatting for return values
|
11
|
+
}
|
12
|
+
|
13
|
+
def ifrb(game)
|
14
|
+
context.prompt_mode = :IFRB
|
15
|
+
|
16
|
+
class <<self
|
17
|
+
def method_missing(sym, *args)
|
18
|
+
if args.empty?
|
19
|
+
sym
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def _load_room(name)
|
27
|
+
context.irb_name = name
|
28
|
+
|
29
|
+
(methods - @_baseline).each do |method|
|
30
|
+
eval "undef #{method}"
|
31
|
+
end
|
32
|
+
|
33
|
+
send(name)
|
34
|
+
|
35
|
+
look if respond_to?(:look)
|
36
|
+
end
|
37
|
+
|
38
|
+
def _format(text, length:60, indent:2)
|
39
|
+
indent = " " * indent
|
40
|
+
|
41
|
+
text.each_line do |line|
|
42
|
+
line.strip!
|
43
|
+
|
44
|
+
if line.empty?
|
45
|
+
puts
|
46
|
+
else
|
47
|
+
while line.length > length
|
48
|
+
break_at = length
|
49
|
+
break_at -= 1 while break_at > 0 && line[break_at] != " "
|
50
|
+
break_at = length if break_at == 0
|
51
|
+
puts indent + line[0, break_at]
|
52
|
+
line = line[break_at+1..-1]
|
53
|
+
end
|
54
|
+
|
55
|
+
puts indent + line if line.length > 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
load "#{game}.rb"
|
63
|
+
@_baseline = methods
|
64
|
+
|
65
|
+
_load_room :start
|
66
|
+
end
|
data/lib/ifrb/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ifrb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamis Buck
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: We spend much of our professional lives in IRB. Why not make a game of
|
14
|
+
it?
|
15
|
+
email:
|
16
|
+
- jamis@jamisbuck.org
|
17
|
+
executables:
|
18
|
+
- ifrb
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- README.md
|
23
|
+
- Rakefile
|
24
|
+
- bin/ifrb
|
25
|
+
- examples/basil.rb
|
26
|
+
- lib/ifrb.rb
|
27
|
+
- lib/ifrb/version.rb
|
28
|
+
homepage: http://github.com/jamis/ifrb
|
29
|
+
licenses:
|
30
|
+
- CC4.0
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.4.5
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: A system for running interactive fiction games within IRB.
|
52
|
+
test_files: []
|