zyps 0.7.3 → 0.7.4
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.
- data/COPYING.txt +674 -674
- data/bin/zyps +24 -12
- data/bin/zyps_demo +8 -0
- data/lib/zyps/conditions.rb +10 -1
- data/lib/zyps.rb +92 -12
- data/test/test_zyps.rb +5 -0
- metadata +58 -51
data/bin/zyps
CHANGED
|
@@ -153,6 +153,9 @@ class Application < Wx::App
|
|
|
153
153
|
@log.debug "Set up a creature generator."
|
|
154
154
|
@generator = CreatureGenerator.new(:environment => @environment)
|
|
155
155
|
|
|
156
|
+
@log.debug "Set the Utility module to cache distances and angles."
|
|
157
|
+
Utility.caching_enabled = true
|
|
158
|
+
|
|
156
159
|
@log.debug "Set up a timer to update the environment."
|
|
157
160
|
milliseconds_per_frame = (1.0 / @options[:fps] * 1000).to_int
|
|
158
161
|
@log.debug "Timer will fire every #{milliseconds_per_frame} milliseconds."
|
|
@@ -190,6 +193,8 @@ class Application < Wx::App
|
|
|
190
193
|
#Copy from View to drawing area.
|
|
191
194
|
render(dc)
|
|
192
195
|
end
|
|
196
|
+
#Almost all distances and angles will be different next update, so clear the cache.
|
|
197
|
+
Utility.clear_caches
|
|
193
198
|
#Keeps dead objects from accumulating and causing hiccups later.
|
|
194
199
|
GC.start
|
|
195
200
|
end
|
|
@@ -644,7 +649,7 @@ class CreatureGenerator
|
|
|
644
649
|
:turn_angle => 90,
|
|
645
650
|
:breed_rate => 10,
|
|
646
651
|
}.merge(options)
|
|
647
|
-
@log.debug "options: #{
|
|
652
|
+
@log.debug "options: #{options.inspect}"
|
|
648
653
|
|
|
649
654
|
@environment = options[:environment]
|
|
650
655
|
@default_size = options[:default_size]
|
|
@@ -692,7 +697,7 @@ class CreatureGenerator
|
|
|
692
697
|
:breed => false,
|
|
693
698
|
:eat => false,
|
|
694
699
|
}.merge(options)
|
|
695
|
-
@log.debug "options: #{
|
|
700
|
+
@log.debug "options: #{options.inspect}"
|
|
696
701
|
|
|
697
702
|
#Create a creature.
|
|
698
703
|
creature = Creature.new(
|
|
@@ -707,35 +712,40 @@ class CreatureGenerator
|
|
|
707
712
|
color.blue += 1
|
|
708
713
|
creature.behaviors << Behavior.new(
|
|
709
714
|
:actions => [TurnAction.new(@turn_rate, @turn_angle)],
|
|
710
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 2)]
|
|
715
|
+
:conditions => [ProximityCondition.new(options[:action_proximity] * 2)],
|
|
716
|
+
:condition_frequency => 20
|
|
711
717
|
)
|
|
712
718
|
end
|
|
713
719
|
if options[:approach]
|
|
714
720
|
color.red += 1
|
|
715
721
|
creature.behaviors << Behavior.new(
|
|
716
722
|
:actions => [ApproachAction.new(@approach_rate)],
|
|
717
|
-
:conditions => [ProximityCondition.new(options[:action_proximity])]
|
|
723
|
+
:conditions => [ProximityCondition.new(options[:action_proximity])],
|
|
724
|
+
:condition_frequency => 10
|
|
718
725
|
)
|
|
719
726
|
end
|
|
720
727
|
if options[:flee]
|
|
721
728
|
color.red += 0.5; color.green += 0.5 #Yellow.
|
|
722
729
|
creature.behaviors << Behavior.new(
|
|
723
730
|
:actions => [FleeAction.new(@flee_rate)],
|
|
724
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.5)]
|
|
731
|
+
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.5)],
|
|
732
|
+
:condition_frequency => 5
|
|
725
733
|
)
|
|
726
734
|
end
|
|
727
735
|
if options[:push]
|
|
728
736
|
color.red += 0.5; color.blue += 0.5 #Purple.
|
|
729
737
|
creature.behaviors << Behavior.new(
|
|
730
738
|
:actions => [PushAction.new(@push_strength)],
|
|
731
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.25)]
|
|
739
|
+
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.25)],
|
|
740
|
+
:condition_frequency => 2
|
|
732
741
|
)
|
|
733
742
|
end
|
|
734
743
|
if options[:pull]
|
|
735
744
|
color.blue += 0.75; color.green += 0.75 #Aqua.
|
|
736
745
|
creature.behaviors << Behavior.new(
|
|
737
746
|
:actions => [PullAction.new(@pull_strength)],
|
|
738
|
-
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.75)]
|
|
747
|
+
:conditions => [ProximityCondition.new(options[:action_proximity] * 0.75)],
|
|
748
|
+
:condition_frequency => 7
|
|
739
749
|
)
|
|
740
750
|
end
|
|
741
751
|
if options[:breed]
|
|
@@ -743,7 +753,8 @@ class CreatureGenerator
|
|
|
743
753
|
color.blue -= 0.1
|
|
744
754
|
creature.behaviors << Behavior.new(
|
|
745
755
|
:actions => [BreedAction.new(@environment, @breed_rate)],
|
|
746
|
-
:conditions => [CollisionCondition.new] #The default ProximityCondition won't do.
|
|
756
|
+
:conditions => [CollisionCondition.new], #The default ProximityCondition won't do.
|
|
757
|
+
:condition_frequency => 1
|
|
747
758
|
)
|
|
748
759
|
end
|
|
749
760
|
if options[:eat]
|
|
@@ -751,15 +762,16 @@ class CreatureGenerator
|
|
|
751
762
|
creature.behaviors << Behavior.new(
|
|
752
763
|
:actions => [EatAction.new(@environment)],
|
|
753
764
|
:conditions => [
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
]
|
|
765
|
+
StrengthCondition.new, #The eater should be as strong or stronger than its dinner.
|
|
766
|
+
CollisionCondition.new #The default ProximityCondition won't do.
|
|
767
|
+
],
|
|
768
|
+
:condition_frequency => 1
|
|
757
769
|
)
|
|
758
770
|
end
|
|
759
771
|
|
|
760
772
|
creature.color = color
|
|
761
773
|
|
|
762
|
-
@log.debug "Created creature: #{creature.
|
|
774
|
+
@log.debug "Created creature: #{creature.to_s}"
|
|
763
775
|
|
|
764
776
|
creature
|
|
765
777
|
|
data/bin/zyps_demo
CHANGED
|
@@ -93,6 +93,12 @@ class Demo < Wx::App
|
|
|
93
93
|
@update_count = 0
|
|
94
94
|
@environment.add_observer(self)
|
|
95
95
|
|
|
96
|
+
say "The Utility module calculates distances and angles between objects."
|
|
97
|
+
say "Utility is sometimes asked to compute the same distance or angle over and over."
|
|
98
|
+
say "We can speed this by returning a cached result instead of re-calculating it."
|
|
99
|
+
say "Let's turn this feature on."
|
|
100
|
+
Utility.caching_enabled = true
|
|
101
|
+
|
|
96
102
|
say "We want to update the environment #{FRAMES_PER_SECOND} times per second."
|
|
97
103
|
milliseconds_per_frame = (1.0 / FRAMES_PER_SECOND * 1000).to_int
|
|
98
104
|
say "So, we'll set up a timer to fire every #{milliseconds_per_frame} milliseconds."
|
|
@@ -100,6 +106,7 @@ class Demo < Wx::App
|
|
|
100
106
|
timer = Wx::Timer.new(self, timer_id)
|
|
101
107
|
say "The timer will trigger the environment update."
|
|
102
108
|
say "Then it copies the updated view's buffer to our window."
|
|
109
|
+
say "We'll clear the cached values from the Utility module to save memory."
|
|
103
110
|
say "We also call the Ruby garbage collector with each update."
|
|
104
111
|
say "This keeps dead objects from accumulating and causing hiccups later."
|
|
105
112
|
evt_timer(timer_id) do
|
|
@@ -107,6 +114,7 @@ class Demo < Wx::App
|
|
|
107
114
|
window.paint do |surface|
|
|
108
115
|
surface.draw_bitmap(view.canvas.buffer, 0, 0, false)
|
|
109
116
|
end
|
|
117
|
+
Utility.clear_caches
|
|
110
118
|
GC.start
|
|
111
119
|
end
|
|
112
120
|
timer.start(milliseconds_per_frame)
|
data/lib/zyps/conditions.rb
CHANGED
|
@@ -67,7 +67,16 @@ end
|
|
|
67
67
|
class CollisionCondition < Condition
|
|
68
68
|
#Returns an array of targets that have collided with the actor.
|
|
69
69
|
def select(actor, targets)
|
|
70
|
-
targets.
|
|
70
|
+
return [] unless targets.length > 0
|
|
71
|
+
#The size of the largest other object
|
|
72
|
+
max_size = targets.map{|t| t.size}.max
|
|
73
|
+
#The maximum distance on a straight line the largest object and self could be and still be touching.
|
|
74
|
+
max_diff = Math.sqrt(actor.size / Math::PI) + Math.sqrt(max_size / Math::PI)
|
|
75
|
+
x_range = (actor.location.x - max_diff .. actor.location.x + max_diff)
|
|
76
|
+
y_range = (actor.location.y - max_diff .. actor.location.y + max_diff)
|
|
77
|
+
targets.select do | target |
|
|
78
|
+
x_range.include?(target.location.x) and y_range.include?(target.location.y) and Utility.collided?(actor, target)
|
|
79
|
+
end
|
|
71
80
|
end
|
|
72
81
|
end
|
|
73
82
|
|
data/lib/zyps.rb
CHANGED
|
@@ -302,20 +302,44 @@ end
|
|
|
302
302
|
#Likewise, the subject can change its own attributes, it can approach or flee from the target, it can spawn new Creatures or GameObjects (like bullets), or anything else.
|
|
303
303
|
class Behavior
|
|
304
304
|
|
|
305
|
+
#An array of Condition subclasses.
|
|
306
|
+
#Condition#select(actor, targets) will be called on each.
|
|
305
307
|
attr_accessor :conditions
|
|
308
|
+
#An array of Action subclasses.
|
|
309
|
+
#Action#start(actor, targets) and action.do(actor, targets) will be called on each when all conditions are true.
|
|
310
|
+
#Action#stop(actor, targets) will be called when any condition is false.
|
|
306
311
|
attr_accessor :actions
|
|
312
|
+
#Number of updates before behavior is allowed to select a new group of targets to act on.
|
|
313
|
+
attr_accessor :condition_frequency
|
|
314
|
+
|
|
315
|
+
#Will be used to distribute condition processing time between all Behaviors with the same condition_frequency.
|
|
316
|
+
@@condition_order = Hash.new {|h, k| h[k] = 0}
|
|
307
317
|
|
|
308
318
|
#Takes a hash with these keys and defaults:
|
|
309
319
|
# :actions => []
|
|
310
320
|
# :conditions => []
|
|
321
|
+
# :condition_frequency => 1
|
|
311
322
|
def initialize (options = {})
|
|
312
323
|
options = {
|
|
313
324
|
:actions => [],
|
|
314
|
-
:conditions => []
|
|
325
|
+
:conditions => [],
|
|
326
|
+
:condition_frequency => 1
|
|
315
327
|
}.merge(options)
|
|
316
|
-
self.actions
|
|
317
|
-
|
|
318
|
-
|
|
328
|
+
self.actions = options[:actions]
|
|
329
|
+
self.conditions = options[:conditions]
|
|
330
|
+
self.condition_frequency = options[:condition_frequency]
|
|
331
|
+
#Tracks number of calls to perform() so conditions can be evaluated with appropriate frequency.
|
|
332
|
+
@condition_evaluation_count = 0
|
|
333
|
+
#Targets currently selected to act upon.
|
|
334
|
+
@current_targets = []
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def condition_frequency= (value)
|
|
338
|
+
#Condition frequency must be 1 or more.
|
|
339
|
+
@condition_frequency = (value >= 1 ? value : 1)
|
|
340
|
+
#This will be used to distribute condition evaluation time among all behaviors with this frequency.
|
|
341
|
+
@condition_order = @@condition_order[@condition_frequency]
|
|
342
|
+
@@condition_order[@condition_frequency] += 1
|
|
319
343
|
end
|
|
320
344
|
|
|
321
345
|
#Make a deep copy.
|
|
@@ -336,19 +360,33 @@ class Behavior
|
|
|
336
360
|
#If no matching targets are found, calls Action#stop(actor, targets) on each Action.
|
|
337
361
|
def perform(actor, targets)
|
|
338
362
|
|
|
339
|
-
|
|
340
|
-
|
|
363
|
+
if condition_evaluation_turn?
|
|
364
|
+
@current_targets = targets.clone
|
|
365
|
+
conditions.each {|condition| @current_targets = condition.select(actor, @current_targets)}
|
|
366
|
+
end
|
|
341
367
|
actions.each do |action|
|
|
342
|
-
if !
|
|
343
|
-
action.start(actor,
|
|
344
|
-
action.do(actor,
|
|
368
|
+
if ! @current_targets.empty?
|
|
369
|
+
action.start(actor, @current_targets) unless action.started?
|
|
370
|
+
action.do(actor, @current_targets)
|
|
345
371
|
else
|
|
346
|
-
action.stop(actor, targets) #Not
|
|
372
|
+
action.stop(actor, targets) #Not @current_targets; that array is empty.
|
|
347
373
|
end
|
|
348
374
|
end
|
|
349
375
|
|
|
376
|
+
|
|
350
377
|
end
|
|
351
378
|
|
|
379
|
+
private
|
|
380
|
+
|
|
381
|
+
#Return true if it's our turn to choose targets, false otherwise.
|
|
382
|
+
def condition_evaluation_turn?
|
|
383
|
+
#Every condition_frequency turns (plus our turn order within the group), return true.
|
|
384
|
+
our_turn = ((@condition_evaluation_count + @condition_order) % @condition_frequency == 0) ? true : false
|
|
385
|
+
#Track number of calls to perform() for staggering condition evaluation.
|
|
386
|
+
@condition_evaluation_count += 1
|
|
387
|
+
our_turn
|
|
388
|
+
end
|
|
389
|
+
|
|
352
390
|
end
|
|
353
391
|
|
|
354
392
|
|
|
@@ -499,8 +537,29 @@ module Utility
|
|
|
499
537
|
|
|
500
538
|
PI2 = Math::PI * 2.0 #:nodoc:
|
|
501
539
|
|
|
540
|
+
#Empty cached return values.
|
|
541
|
+
def Utility.clear_caches
|
|
542
|
+
@@angles = Hash.new {|h, k| h[k] = {}}
|
|
543
|
+
@@distances = Hash.new {|h, k| h[k] = {}}
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
#Initialize caches for return values.
|
|
547
|
+
Utility.clear_caches
|
|
548
|
+
|
|
549
|
+
#Turn caching of return values on or off.
|
|
550
|
+
@@caching_enabled = false
|
|
551
|
+
def Utility.caching_enabled= (value)
|
|
552
|
+
@@caching_enabled = value
|
|
553
|
+
Utility.clear_caches if ! @@caching_enabled
|
|
554
|
+
end
|
|
555
|
+
|
|
502
556
|
#Get the angle (in degrees) from one Location to another.
|
|
503
557
|
def Utility.find_angle(origin, target)
|
|
558
|
+
if @@caching_enabled
|
|
559
|
+
#Return cached angle if there is one.
|
|
560
|
+
return @@angles[origin][target] if @@angles[origin][target]
|
|
561
|
+
return @@angles[target][origin] if @@angles[target][origin]
|
|
562
|
+
end
|
|
504
563
|
#Get vector from origin to target.
|
|
505
564
|
x_difference = target.x - origin.x
|
|
506
565
|
y_difference = target.y - origin.y
|
|
@@ -509,16 +568,37 @@ module Utility
|
|
|
509
568
|
#Result will range from negative Pi to Pi, so correct it.
|
|
510
569
|
radians += PI2 if radians < 0
|
|
511
570
|
#Convert to degrees.
|
|
512
|
-
to_degrees(radians)
|
|
571
|
+
angle = to_degrees(radians)
|
|
572
|
+
#Cache angle if caching enabled.
|
|
573
|
+
if @@caching_enabled
|
|
574
|
+
@@angles[origin][target] = angle
|
|
575
|
+
#angle + 180 = angle from target to origin.
|
|
576
|
+
@@angles[target][origin] = (angle + 180 % 360)
|
|
577
|
+
end
|
|
578
|
+
#Return result.
|
|
579
|
+
angle
|
|
513
580
|
end
|
|
514
581
|
|
|
515
582
|
#Get the distance from one Location to another.
|
|
516
583
|
def Utility.find_distance(origin, target)
|
|
584
|
+
if @@caching_enabled
|
|
585
|
+
#Return cached distance if there is one.
|
|
586
|
+
return @@distances[origin][target] if @@distances[origin][target]
|
|
587
|
+
end
|
|
517
588
|
#Get vector from origin to target.
|
|
518
589
|
x_difference = origin.x - target.x
|
|
519
590
|
y_difference = origin.y - target.y
|
|
520
591
|
#Get distance.
|
|
521
|
-
Math.sqrt(x_difference ** 2 + y_difference ** 2)
|
|
592
|
+
distance = Math.sqrt(x_difference ** 2 + y_difference ** 2)
|
|
593
|
+
#Cache distance if caching enabled.
|
|
594
|
+
if @@caching_enabled
|
|
595
|
+
#Origin to target distance = target to origin distance.
|
|
596
|
+
#Cache such that either will be found.
|
|
597
|
+
@@distances[origin][target] = distance
|
|
598
|
+
@@distances[target][origin] = distance
|
|
599
|
+
end
|
|
600
|
+
#Return result.
|
|
601
|
+
distance
|
|
522
602
|
end
|
|
523
603
|
|
|
524
604
|
#Convert radians to degrees.
|
data/test/test_zyps.rb
CHANGED
metadata
CHANGED
|
@@ -1,81 +1,88 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
|
-
rubygems_version: 0.9.2
|
|
3
|
-
specification_version: 1
|
|
4
2
|
name: zyps
|
|
5
3
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 0.7.
|
|
7
|
-
date: 2008-02-04 00:00:00 -07:00
|
|
8
|
-
summary: A game library for Ruby
|
|
9
|
-
require_paths:
|
|
10
|
-
- lib
|
|
11
|
-
email: jay@mcgavren.com
|
|
12
|
-
homepage: http://jay.mcgavren.com/zyps/
|
|
13
|
-
rubyforge_project: zyps
|
|
14
|
-
description:
|
|
15
|
-
autorequire: zyps
|
|
16
|
-
default_executable:
|
|
17
|
-
bindir: bin
|
|
18
|
-
has_rdoc: true
|
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
|
-
requirements:
|
|
21
|
-
- - ">"
|
|
22
|
-
- !ruby/object:Gem::Version
|
|
23
|
-
version: 0.0.0
|
|
24
|
-
version:
|
|
4
|
+
version: 0.7.4
|
|
25
5
|
platform: ruby
|
|
26
|
-
signing_key:
|
|
27
|
-
cert_chain:
|
|
28
|
-
post_install_message:
|
|
29
6
|
authors:
|
|
30
7
|
- Jay McGavren
|
|
8
|
+
autorequire: zyps
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-02-05 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: wxruby
|
|
17
|
+
version_requirement:
|
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
19
|
+
requirements:
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 1.9.2
|
|
23
|
+
version:
|
|
24
|
+
description:
|
|
25
|
+
email: jay@mcgavren.com
|
|
26
|
+
executables:
|
|
27
|
+
- zyps
|
|
28
|
+
extensions: []
|
|
29
|
+
|
|
30
|
+
extra_rdoc_files:
|
|
31
|
+
- README.txt
|
|
32
|
+
- COPYING.LESSER.txt
|
|
33
|
+
- COPYING.txt
|
|
31
34
|
files:
|
|
32
35
|
- COPYING.LESSER.txt
|
|
33
36
|
- COPYING.txt
|
|
34
|
-
- README.txt
|
|
35
37
|
- README_windows.txt
|
|
38
|
+
- README.txt
|
|
36
39
|
- bin/zyps
|
|
37
40
|
- bin/zyps_demo
|
|
38
41
|
- lib/zyps
|
|
39
|
-
- lib/zyps/actions.rb
|
|
40
|
-
- lib/zyps/conditions.rb
|
|
41
|
-
- lib/zyps/environmental_factors.rb
|
|
42
|
-
- lib/zyps/remote.rb
|
|
43
42
|
- lib/zyps/views
|
|
44
43
|
- lib/zyps/views/canvas
|
|
45
44
|
- lib/zyps/views/canvas/wx.rb
|
|
46
45
|
- lib/zyps/views/trails.rb
|
|
46
|
+
- lib/zyps/actions.rb
|
|
47
|
+
- lib/zyps/environmental_factors.rb
|
|
48
|
+
- lib/zyps/conditions.rb
|
|
49
|
+
- lib/zyps/remote.rb
|
|
47
50
|
- lib/zyps.rb
|
|
48
|
-
- test/test_zyps.rb
|
|
49
51
|
- test/zyps
|
|
50
|
-
- test/zyps/test_actions.rb
|
|
51
52
|
- test/zyps/test_behaviors.rb
|
|
52
|
-
- test/zyps/
|
|
53
|
+
- test/zyps/test_actions.rb
|
|
53
54
|
- test/zyps/test_environmental_factors.rb
|
|
55
|
+
- test/zyps/test_conditions.rb
|
|
54
56
|
- test/zyps/test_remote.rb
|
|
55
|
-
test_files:
|
|
56
57
|
- test/test_zyps.rb
|
|
58
|
+
has_rdoc: true
|
|
59
|
+
homepage: http://jay.mcgavren.com/zyps/
|
|
60
|
+
post_install_message:
|
|
57
61
|
rdoc_options:
|
|
58
62
|
- --title
|
|
59
63
|
- Zyps - A game library for Ruby
|
|
60
64
|
- --main
|
|
61
65
|
- README.txt
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
require_paths:
|
|
67
|
+
- lib
|
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: "0"
|
|
73
|
+
version:
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: "0"
|
|
79
|
+
version:
|
|
70
80
|
requirements: []
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- !ruby/object:Gem::Version
|
|
80
|
-
version: 1.9.2
|
|
81
|
-
version:
|
|
82
|
+
rubyforge_project: zyps
|
|
83
|
+
rubygems_version: 1.0.1
|
|
84
|
+
signing_key:
|
|
85
|
+
specification_version: 2
|
|
86
|
+
summary: A game library for Ruby
|
|
87
|
+
test_files:
|
|
88
|
+
- test/test_zyps.rb
|