jemini 2009.10.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/README.txt +9 -0
  2. data/bin/jemini +26 -0
  3. data/lib/ibxm.jar +0 -0
  4. data/lib/jinput.jar +0 -0
  5. data/lib/jogg-0.0.7.jar +0 -0
  6. data/lib/jorbis-0.0.15.jar +0 -0
  7. data/lib/jruby-complete.jar +0 -0
  8. data/lib/lwjgl.jar +0 -0
  9. data/lib/lwjgl_util_applet.jar +0 -0
  10. data/lib/native_files/OpenAL32.dll +0 -0
  11. data/lib/native_files/jinput-dx8.dll +0 -0
  12. data/lib/native_files/jinput-dx8_64.dll +0 -0
  13. data/lib/native_files/jinput-raw.dll +0 -0
  14. data/lib/native_files/jinput-raw_64.dll +0 -0
  15. data/lib/native_files/jinput-wintab.dll +0 -0
  16. data/lib/native_files/libjinput-linux.so +0 -0
  17. data/lib/native_files/libjinput-linux64.so +0 -0
  18. data/lib/native_files/libjinput-osx.jnilib +0 -0
  19. data/lib/native_files/liblwjgl.jnilib +0 -0
  20. data/lib/native_files/liblwjgl.so +0 -0
  21. data/lib/native_files/liblwjgl64.so +0 -0
  22. data/lib/native_files/libopenal.so +0 -0
  23. data/lib/native_files/lwjgl.dll +0 -0
  24. data/lib/native_files/openal.dylib +0 -0
  25. data/lib/natives-linux.jar +0 -0
  26. data/lib/natives-mac.jar +0 -0
  27. data/lib/natives-win32.jar +0 -0
  28. data/lib/phys2d.jar +0 -0
  29. data/lib/slick.jar +0 -0
  30. data/package/jar/jemini.jar +0 -0
  31. data/src/behavior.rb +248 -0
  32. data/src/behavior_event.rb +23 -0
  33. data/src/behaviors/animated_image.rb +88 -0
  34. data/src/behaviors/audible.rb +16 -0
  35. data/src/behaviors/axis_stateful.rb +35 -0
  36. data/src/behaviors/bounding_box_collidable.rb +27 -0
  37. data/src/behaviors/cardinal_movable.rb +121 -0
  38. data/src/behaviors/clickable.rb +19 -0
  39. data/src/behaviors/countable.rb +32 -0
  40. data/src/behaviors/debug_physical.rb +43 -0
  41. data/src/behaviors/debug_tangible.rb +31 -0
  42. data/src/behaviors/drawable.rb +7 -0
  43. data/src/behaviors/drawable_image.rb +111 -0
  44. data/src/behaviors/drawable_line.rb +32 -0
  45. data/src/behaviors/drawable_shape.rb +48 -0
  46. data/src/behaviors/fading_image_trail_emittable.rb +32 -0
  47. data/src/behaviors/game_object_emittable.rb +13 -0
  48. data/src/behaviors/grid_bound.rb +108 -0
  49. data/src/behaviors/handles_events.rb +33 -0
  50. data/src/behaviors/inertial.rb +14 -0
  51. data/src/behaviors/magnetic.rb +34 -0
  52. data/src/behaviors/metered.rb +3 -0
  53. data/src/behaviors/movable.rb +81 -0
  54. data/src/behaviors/particle_emitter.rb +27 -0
  55. data/src/behaviors/physical.rb +384 -0
  56. data/src/behaviors/physical_cardinal_movable.rb +111 -0
  57. data/src/behaviors/physical_image.rb +45 -0
  58. data/src/behaviors/pointer.rb +30 -0
  59. data/src/behaviors/pressable.rb +17 -0
  60. data/src/behaviors/regional.rb +76 -0
  61. data/src/behaviors/rotates_to_point.rb +19 -0
  62. data/src/behaviors/spatial.rb +43 -0
  63. data/src/behaviors/stateful.rb +33 -0
  64. data/src/behaviors/taggable.rb +28 -0
  65. data/src/behaviors/tangible.rb +59 -0
  66. data/src/behaviors/timeable.rb +88 -0
  67. data/src/behaviors/top_down_vehicle.rb +42 -0
  68. data/src/behaviors/triangle_trail_emittable.rb +46 -0
  69. data/src/behaviors/unique.rb +0 -0
  70. data/src/behaviors/updates.rb +8 -0
  71. data/src/behaviors/updates_at_consistant_rate.rb +28 -0
  72. data/src/behaviors/vectored_movement.rb +48 -0
  73. data/src/behaviors/world_collidable.rb +9 -0
  74. data/src/color.rb +70 -0
  75. data/src/events/grid_changed_event.rb +8 -0
  76. data/src/events/physical_message.rb +9 -0
  77. data/src/events/tangible_collision_event.rb +8 -0
  78. data/src/file_system.rb +17 -0
  79. data/src/game.rb +110 -0
  80. data/src/game_object.rb +176 -0
  81. data/src/game_objects/background.rb +10 -0
  82. data/src/game_objects/fading_image.rb +23 -0
  83. data/src/game_objects/tangible_object.rb +4 -0
  84. data/src/game_objects/text.rb +71 -0
  85. data/src/game_objects/triangle_trail.rb +85 -0
  86. data/src/game_state.rb +164 -0
  87. data/src/inflector.rb +68 -0
  88. data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
  89. data/src/jemini.rb +31 -0
  90. data/src/jemini_version.rb +4 -0
  91. data/src/listenable_mixin.rb +15 -0
  92. data/src/logger_mixin.rb +11 -0
  93. data/src/managers/basic_game_object_manager.rb +95 -0
  94. data/src/managers/basic_physics_manager.rb +95 -0
  95. data/src/managers/basic_render_manager.rb +49 -0
  96. data/src/managers/basic_tile_manager.rb +3 -0
  97. data/src/managers/basic_update_manager.rb +30 -0
  98. data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
  99. data/src/managers/input_manager.rb +161 -0
  100. data/src/managers/input_support/input_binding.rb +77 -0
  101. data/src/managers/input_support/input_builder.rb +44 -0
  102. data/src/managers/input_support/input_listener.rb +74 -0
  103. data/src/managers/input_support/input_message.rb +5 -0
  104. data/src/managers/input_support/joystick_listener.rb +53 -0
  105. data/src/managers/input_support/key_listener.rb +27 -0
  106. data/src/managers/input_support/mouse_listener.rb +38 -0
  107. data/src/managers/input_support/slick_input_listener.rb +20 -0
  108. data/src/managers/input_support/slick_input_message.rb +11 -0
  109. data/src/managers/input_support/slick_input_translator.rb +15 -0
  110. data/src/managers/message_queue.rb +60 -0
  111. data/src/managers/network_manager.rb +41 -0
  112. data/src/managers/render_support/hardware_cursor.rb +13 -0
  113. data/src/managers/resource_manager.rb +167 -0
  114. data/src/managers/sound_manager.rb +47 -0
  115. data/src/managers/tag_manager.rb +47 -0
  116. data/src/managers/tangible_manager.rb +36 -0
  117. data/src/math.rb +23 -0
  118. data/src/org/rubyforge/rawr/Main.java +67 -0
  119. data/src/platform.rb +28 -0
  120. data/src/proc_enhancement.rb +5 -0
  121. data/src/project_generator.rb +138 -0
  122. data/src/resource.rb +31 -0
  123. data/src/spline.rb +13 -0
  124. data/src/states/input_diagnostic_state.rb +53 -0
  125. data/src/vector.rb +143 -0
  126. data/test/test_state.rb +3 -0
  127. metadata +188 -0
@@ -0,0 +1,31 @@
1
+ module Jemini
2
+ class Resource
3
+ puts "+++++++++++++++++++"
4
+ puts $0
5
+ puts "In jar? #{File.in_jar?($0)}"
6
+ puts "+++++++++++++++++++"
7
+ # go up two dirs from lib/java
8
+ @@base_path = File.in_jar?($0) ? File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'data.jar!', 'data')) : 'data'
9
+
10
+ def self.base_path
11
+ @@base_path
12
+ end
13
+
14
+ def self.path_of(file)
15
+ #TODO: Find the JRuby classloader and use that?
16
+ class_loader = org.newdawn.slick.geom.Vector2f.java_class.class_loader
17
+ jarred_path = file
18
+ dev_path = File.join('..', file)
19
+
20
+ # log.debug "jarred path: #{jarred_path}"
21
+ # log.debug "dev path: #{dev_path}"
22
+ if class_loader.find_resource(jarred_path)
23
+ jarred_path
24
+ elsif File.exist?(dev_path)
25
+ dev_path
26
+ else
27
+ jarred_path
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ class Spline
2
+ def initialize(*x_y_arrays)
3
+ @points = x_y_arrays
4
+ @current_point_index = 0
5
+ end
6
+
7
+ def succ
8
+ y = @points[@current_point_index][1]
9
+ @current_point_index += 1
10
+ @current_point_index = 0 if @current_point_index >= @points.size
11
+ y
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ class InputDiagnosticState < Jemini::GameState
2
+ def load
3
+ @input = manager(:input)
4
+ @raw_input = @input.instance_variable_get(:@raw_input)
5
+ @input.connected_joystick_size.times do |joystick_index|
6
+ width = joystick_width_offset(joystick_index)
7
+ @joystick_height_offset = 40
8
+ text = create :Text, width, @joystick_height_offset , "Controller #{joystick_index}"
9
+ text.x += text.text_width / 2
10
+ map_all_buttons_for_joystick joystick_index
11
+ map_all_axes_for_joystick joystick_index
12
+ end
13
+ end
14
+
15
+ def map_all_axes_for_joystick(joystick_id)
16
+ @raw_input.get_axis_count(joystick_id).times do |axis_id|
17
+ @joystick_height_offset += 10
18
+ axis_text = create :Text, joystick_width_offset(joystick_id), @joystick_height_offset, "axis"
19
+ axis_text.add_behavior :Updates
20
+ axis_text.on_update do
21
+ # TODO: Split name and value for easier alignment
22
+ axis_name = @raw_input.get_axis_name(joystick_id, axis_id)
23
+ axis_value = @raw_input.get_axis_value(joystick_id, axis_id)
24
+ axis_text.text = "#{axis_name}: #{"%+.2f" % axis_value}"
25
+ axis_text.x = joystick_width_offset(joystick_id) + 20 + (axis_text.text_width / 2)
26
+ end
27
+ end
28
+ end
29
+
30
+ def joystick_width_offset(joystick_index)
31
+ 80 + (joystick_index * 80)
32
+ end
33
+
34
+ def map_all_buttons_for_joystick(joystick_id)
35
+ 25.times do |button_id|
36
+ begin
37
+ @raw_input.is_button_pressed(button_id, joystick_id)
38
+ rescue java.lang.ArrayIndexOutOfBoundsException
39
+ return # All done if we reached the end
40
+ end
41
+
42
+ @joystick_height_offset += 10
43
+ button_text = create :Text, joystick_width_offset(joystick_id), @joystick_height_offset, "button"
44
+ button_text.add_behavior :Updates
45
+ button_text.on_update do
46
+ button_down = @raw_input.is_button_pressed(button_id, joystick_id)
47
+ button_down_text = button_down ? "Down" : "Up"
48
+ button_text.text = "#{button_id}: #{button_down_text}"
49
+ button_text.x = joystick_width_offset(joystick_id) + 20 + (button_text.text_width / 2)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,143 @@
1
+ # TODO: Remove reliance on Slick's vector
2
+ class Vector
3
+ SlickVector = Java::org::newdawn::slick::geom::Vector2f
4
+
5
+ attr_reader :native_vector
6
+
7
+ def self.from_polar_vector(magnitude, angle)
8
+ w = Math.sin(Jemini::Math.degrees_to_radians(angle))
9
+ h = -Math.cos(Jemini::Math.degrees_to_radians(angle))
10
+ return new(w * magnitude, h * magnitude)
11
+ end
12
+
13
+ def initialize(x = 0.0, y = 0.0, z = nil)
14
+ @native_vector = SlickVector.new(x, y)
15
+ end
16
+
17
+ ORIGIN = new(0.0, 0.0).freeze
18
+
19
+ def dup
20
+ self.class.new(x, y)
21
+ end
22
+
23
+ # often used for center calculations. Other multiples are not needed
24
+ def half
25
+ Vector.new(x / 2.0, y / 2.0)
26
+ end
27
+
28
+ def ==(other_vector)
29
+ return false unless other_vector.respond_to?(:x) || other_vector.respond_to?(:y)
30
+ x == other_vector.x && y == other_vector.y
31
+ end
32
+
33
+ def +(other_vector)
34
+ self.class.new(x + other_vector.x, y + other_vector.y)
35
+ end
36
+
37
+ def -(other_vector)
38
+ self.class.new(x - other_vector.x, y - other_vector.y)
39
+ end
40
+
41
+ def x
42
+ @native_vector.x
43
+ end
44
+
45
+ def y
46
+ @native_vector.y
47
+ end
48
+
49
+ def z
50
+ @native_vector.z
51
+ end
52
+
53
+ def x=(new_x)
54
+ @native_vector.x = new_x
55
+ end
56
+
57
+ def y=(new_y)
58
+ @native_vector.y = new_y
59
+ end
60
+
61
+ def z=(new_z)
62
+ @native_vector.z = new_z
63
+ end
64
+
65
+ def to_phys2d_vector
66
+ Java::net::phys2d::math::Vector2f.new(@native_vector.x, @native_vector.y)
67
+ end
68
+
69
+ def to_slick_vector
70
+ @native_vector
71
+ end
72
+
73
+ def distance_from(other_vector)
74
+ (((x - other_vector.x) ** 2) + ((y - other_vector.y) ** 2)) ** (1.0 / 2.0)
75
+ end
76
+
77
+ def angle_from(other_vector)
78
+ #TODO: Adding 90 degrees indicates to me that this is the wrong trig function.
79
+ # Although it's good for perpendicular angles, which we'll need a method for.
80
+ Jemini::Math.radians_to_degrees(Math.atan2(y - other_vector.y, x - other_vector.x)) + 90.0
81
+ end
82
+
83
+ def midpoint_of(other_vector)
84
+ Vector.new((x + other_vector.x) / 2.0, (y + other_vector.y) / 2.0)
85
+ end
86
+
87
+ def pivot_around_degrees(other_vector, rotation)
88
+ pivot_around(other_vector, Jemini::Math.degrees_to_radians(rotation))
89
+ end
90
+
91
+ def pivot_around(other_vector, rotation)
92
+ diff_x = x - other_vector.x
93
+ diff_y = y - other_vector.y
94
+ sine = Math.sin(rotation)
95
+ cosine = Math.cos(rotation)
96
+ rotated_x = (cosine * diff_x) - (sine * diff_y)
97
+ rotated_y = (sine * diff_x) + (cosine * diff_y)
98
+ self.class.new rotated_x, rotated_y
99
+ end
100
+
101
+ def polar_angle
102
+ Math.atan2(y, x)
103
+ end
104
+
105
+ def polar_angle_degrees
106
+ Jemini::Math.radians_to_degrees polar_angle
107
+ end
108
+
109
+ def magnitude
110
+ Math::sqrt((x ** 2) + (y ** 2))
111
+ end
112
+
113
+ # TODO: Implement -@ and +@, the negate and plus(?) unary operators
114
+ def negate
115
+ self.class.new(-x, -y)
116
+ end
117
+
118
+ def near?(other_vector, radius)
119
+ distance_from(other_vector) <= radius
120
+ end
121
+
122
+ def to_s
123
+ "<#{self.class} - X: #{x} Y: #{y}>"
124
+ end
125
+
126
+ def inspect
127
+ "<#{super} - X: #{x} Y: #{y}>"
128
+ end
129
+ end
130
+
131
+ class Java::net::phys2d::math::Vector2f
132
+ def +(other_vector)
133
+ Vector.new(x + other_vector.x, y + other_vector.y)
134
+ end
135
+
136
+ def to_vector
137
+ Vector.new(x, y)
138
+ end
139
+
140
+ def to_phys2d_vector
141
+ self
142
+ end
143
+ end
@@ -0,0 +1,3 @@
1
+ class TestState < Jemini::GameState
2
+
3
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jemini
3
+ version: !ruby/object:Gem::Version
4
+ version: 2009.10.27
5
+ platform: ruby
6
+ authors:
7
+ - Logan Barnett, David Koontz, Jay McGavren
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-27 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rawr
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.3.7
24
+ version:
25
+ description: Jemini is a game library designed to allow creation of reusable features. How many times has someone implemented the aiming on a first person shooter, or a minimap on a real time strategy? Jemini comes packaged with lots of behaviors out of the box, with the ability to easily author more. Jemini uses Phys2D and Slick for physics and graphics, with 3D on the roadmap.
26
+ email: logustus@gmail.com
27
+ executables:
28
+ - jemini
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.txt
33
+ files:
34
+ - src/behavior.rb
35
+ - src/behavior_event.rb
36
+ - src/color.rb
37
+ - src/file_system.rb
38
+ - src/game.rb
39
+ - src/game_object.rb
40
+ - src/game_state.rb
41
+ - src/inflector.rb
42
+ - src/jemini.rb
43
+ - src/jemini_version.rb
44
+ - src/listenable_mixin.rb
45
+ - src/logger_mixin.rb
46
+ - src/math.rb
47
+ - src/platform.rb
48
+ - src/proc_enhancement.rb
49
+ - src/project_generator.rb
50
+ - src/resource.rb
51
+ - src/spline.rb
52
+ - src/vector.rb
53
+ - src/behaviors/animated_image.rb
54
+ - src/behaviors/audible.rb
55
+ - src/behaviors/axis_stateful.rb
56
+ - src/behaviors/bounding_box_collidable.rb
57
+ - src/behaviors/cardinal_movable.rb
58
+ - src/behaviors/clickable.rb
59
+ - src/behaviors/countable.rb
60
+ - src/behaviors/debug_physical.rb
61
+ - src/behaviors/debug_tangible.rb
62
+ - src/behaviors/drawable.rb
63
+ - src/behaviors/drawable_image.rb
64
+ - src/behaviors/drawable_line.rb
65
+ - src/behaviors/drawable_shape.rb
66
+ - src/behaviors/fading_image_trail_emittable.rb
67
+ - src/behaviors/game_object_emittable.rb
68
+ - src/behaviors/grid_bound.rb
69
+ - src/behaviors/handles_events.rb
70
+ - src/behaviors/inertial.rb
71
+ - src/behaviors/magnetic.rb
72
+ - src/behaviors/metered.rb
73
+ - src/behaviors/movable.rb
74
+ - src/behaviors/particle_emitter.rb
75
+ - src/behaviors/physical.rb
76
+ - src/behaviors/physical_cardinal_movable.rb
77
+ - src/behaviors/physical_image.rb
78
+ - src/behaviors/pointer.rb
79
+ - src/behaviors/pressable.rb
80
+ - src/behaviors/regional.rb
81
+ - src/behaviors/rotates_to_point.rb
82
+ - src/behaviors/spatial.rb
83
+ - src/behaviors/stateful.rb
84
+ - src/behaviors/taggable.rb
85
+ - src/behaviors/tangible.rb
86
+ - src/behaviors/timeable.rb
87
+ - src/behaviors/top_down_vehicle.rb
88
+ - src/behaviors/triangle_trail_emittable.rb
89
+ - src/behaviors/unique.rb
90
+ - src/behaviors/updates.rb
91
+ - src/behaviors/updates_at_consistant_rate.rb
92
+ - src/behaviors/vectored_movement.rb
93
+ - src/behaviors/world_collidable.rb
94
+ - src/events/grid_changed_event.rb
95
+ - src/events/physical_message.rb
96
+ - src/events/tangible_collision_event.rb
97
+ - src/game_objects/background.rb
98
+ - src/game_objects/fading_image.rb
99
+ - src/game_objects/tangible_object.rb
100
+ - src/game_objects/text.rb
101
+ - src/game_objects/triangle_trail.rb
102
+ - src/input_helpers/joystick_dead_zone_filter.rb
103
+ - src/managers/basic_game_object_manager.rb
104
+ - src/managers/basic_physics_manager.rb
105
+ - src/managers/basic_render_manager.rb
106
+ - src/managers/basic_tile_manager.rb
107
+ - src/managers/basic_update_manager.rb
108
+ - src/managers/input_manager.rb
109
+ - src/managers/message_queue.rb
110
+ - src/managers/network_manager.rb
111
+ - src/managers/resource_manager.rb
112
+ - src/managers/sound_manager.rb
113
+ - src/managers/tag_manager.rb
114
+ - src/managers/tangible_manager.rb
115
+ - src/managers/diagnostic/diagnostic_input_manager.rb
116
+ - src/managers/input_support/input_binding.rb
117
+ - src/managers/input_support/input_builder.rb
118
+ - src/managers/input_support/input_listener.rb
119
+ - src/managers/input_support/input_message.rb
120
+ - src/managers/input_support/joystick_listener.rb
121
+ - src/managers/input_support/key_listener.rb
122
+ - src/managers/input_support/mouse_listener.rb
123
+ - src/managers/input_support/slick_input_listener.rb
124
+ - src/managers/input_support/slick_input_message.rb
125
+ - src/managers/input_support/slick_input_translator.rb
126
+ - src/managers/render_support/hardware_cursor.rb
127
+ - src/org/rubyforge/rawr/Main.java
128
+ - src/states/input_diagnostic_state.rb
129
+ - lib/ibxm.jar
130
+ - lib/jinput.jar
131
+ - lib/jogg-0.0.7.jar
132
+ - lib/jorbis-0.0.15.jar
133
+ - lib/jruby-complete.jar
134
+ - lib/lwjgl.jar
135
+ - lib/lwjgl_util_applet.jar
136
+ - lib/natives-linux.jar
137
+ - lib/natives-mac.jar
138
+ - lib/natives-win32.jar
139
+ - lib/phys2d.jar
140
+ - lib/slick.jar
141
+ - lib/native_files/jinput-dx8.dll
142
+ - lib/native_files/jinput-dx8_64.dll
143
+ - lib/native_files/jinput-raw.dll
144
+ - lib/native_files/jinput-raw_64.dll
145
+ - lib/native_files/jinput-wintab.dll
146
+ - lib/native_files/libjinput-linux.so
147
+ - lib/native_files/libjinput-linux64.so
148
+ - lib/native_files/libjinput-osx.jnilib
149
+ - lib/native_files/liblwjgl.jnilib
150
+ - lib/native_files/liblwjgl.so
151
+ - lib/native_files/liblwjgl64.so
152
+ - lib/native_files/libopenal.so
153
+ - lib/native_files/lwjgl.dll
154
+ - lib/native_files/openal.dylib
155
+ - lib/native_files/OpenAL32.dll
156
+ - package/jar/jemini.jar
157
+ - README.txt
158
+ has_rdoc: true
159
+ homepage: http://rubyforge.org/projects/jemini/
160
+ licenses: []
161
+
162
+ post_install_message:
163
+ rdoc_options:
164
+ - --main
165
+ - README.txt
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: "0"
173
+ version:
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: "0"
179
+ version:
180
+ requirements: []
181
+
182
+ rubyforge_project: jemini
183
+ rubygems_version: 1.3.5
184
+ signing_key:
185
+ specification_version: 3
186
+ summary: Jemini is a Ruby game engine that separates the game logic from reusable game features. Includes hardware accelerated graphics, physics, standalone distros, and more.
187
+ test_files:
188
+ - test/test_state.rb