summaryrefslogtreecommitdiffhomepage
path: root/dragon
diff options
context:
space:
mode:
authorAmir Rajan <[email protected]>2021-01-18 12:08:34 -0600
committerAmir Rajan <[email protected]>2021-01-18 12:08:34 -0600
commita4b9c048a1d751f5226833bb0c527ba1a8ac5d09 (patch)
tree3f2535e7a6272e796d50e7f07c906d4c9eb1b14a /dragon
parenta24a71805b1924ae7f80776c736f94575c171d2c (diff)
downloaddragonruby-game-toolkit-contrib-a4b9c048a1d751f5226833bb0c527ba1a8ac5d09.tar.gz
dragonruby-game-toolkit-contrib-a4b9c048a1d751f5226833bb0c527ba1a8ac5d09.zip
Synced with 2.3.
Diffstat (limited to 'dragon')
-rw-r--r--dragon/args.rb4
-rw-r--r--dragon/attr_gtk.rb4
-rw-r--r--dragon/autocomplete.rb131
-rw-r--r--dragon/console.rb4
-rw-r--r--dragon/draw.rb76
-rw-r--r--dragon/easing.rb4
-rw-r--r--dragon/framerate.rb83
-rw-r--r--dragon/framerate_diagnostics.rb1
-rw-r--r--dragon/geometry.rb62
-rw-r--r--dragon/inputs.rb6
-rw-r--r--dragon/ios_wizard.rb31
-rw-r--r--dragon/layout.rb7
-rw-r--r--dragon/numeric.rb22
-rw-r--r--dragon/readme_docs.rb45
14 files changed, 408 insertions, 72 deletions
diff --git a/dragon/args.rb b/dragon/args.rb
index 6eb644e..43e6a18 100644
--- a/dragon/args.rb
+++ b/dragon/args.rb
@@ -222,5 +222,9 @@ module GTK
def controller_two
@inputs.controller_two
end
+
+ def autocomplete_methods
+ [:inputs, :outputs, :gtk, :state, :geometry, :audio, :grid, :layout]
+ end
end
end
diff --git a/dragon/attr_gtk.rb b/dragon/attr_gtk.rb
index c4e03a8..2f2ccc5 100644
--- a/dragon/attr_gtk.rb
+++ b/dragon/attr_gtk.rb
@@ -42,4 +42,8 @@ module AttrGTK
def geometry
args.geometry
end
+
+ def layout
+ args.layout
+ end
end
diff --git a/dragon/autocomplete.rb b/dragon/autocomplete.rb
new file mode 100644
index 0000000..f5f03b4
--- /dev/null
+++ b/dragon/autocomplete.rb
@@ -0,0 +1,131 @@
+# Copyright 2019 DragonRuby LLC
+# MIT License
+# autocomplete.rb has been released under MIT (*only this file*).
+
+module GTK
+ class Runtime
+ module Autocomplete
+ def autocomplete_parse opts
+ if opts[:file] && !opts[:text]
+ opts[:text] = read_file opts[:file]
+ end
+
+ text = opts[:text]
+ index = opts[:index]
+ sum = 0
+ lines = text.each_line.to_a.map do |l|
+ sum += l.length
+ { line: l, length: l.length, sum: sum }
+ end
+ cursor_line = lines.find { |l| l[:sum] >= index }
+ previous_line = lines.find { |l| l[:sum] < index }
+ previous_line ||= { sum: 0 }
+ if cursor_line
+ sub_index = index - previous_line[:sum]
+ word = (cursor_line[:line][0..sub_index - 1]).strip
+ token = (word.split " ")[-1]
+ dots = (token.split ".")
+ dot = dots[-1]
+ end
+
+ {
+ text: opts[:text],
+ file: opts[:file],
+ index: opts[:index],
+ cursor_line: cursor_line,
+ previous_line: previous_line,
+ word: word,
+ token: token,
+ dots: dots,
+ dot: dot
+ }
+ end
+
+ def autocomplete_filter_methods keys, *ignores
+ ignores ||= []
+ ignores = [ignores].flatten
+ keys = keys.map { |k| k.to_s }
+ others = ["def", "end"] +
+ [ :entity_keys_by_ref,
+ :entity_name,
+ :as_hash,
+ :clear!,
+ :created_at_elapsed,
+ :entity_id,
+ "entity_id=",
+ "tick_count=",
+ :global_created_at_elapsed,
+ :load_entity_data!,
+ :meta,
+ :meta!,
+ :new?,
+ :old?,
+ :original_eq_eq, :set!,
+ :update_entity_keys_by_ref,
+ :with_meta] +
+ ignores + keys.find_all { |k| k.to_s.to_i.to_s == k.to_s }
+
+ final = (keys - (others.map { |m| m.to_s })).uniq
+ final
+ end
+
+ def suggest_autocompletion opts
+ parse_result = autocomplete_parse opts
+ return [] unless parse_result[:cursor_line]
+ text = parse_result[:text]
+ word = parse_result[:word]
+ token = parse_result[:token]
+ dots = parse_result[:dots]
+ dot = parse_result[:dot]
+
+ return [] if word.strip.start_with? "#"
+
+ if word[-1] == "." && token
+ lookup = {
+ 'args' => lambda { $gtk.args },
+ 'inputs' => lambda { $gtk.args.inputs },
+ 'outputs' => lambda { $gtk.args.outputs },
+ 'layout' => lambda { $gtk.args.outputs },
+ 'keyboard' => lambda { $gtk.args.keyboard },
+ 'key_down' => lambda { $gtk.args.keyboard.key_down },
+ 'key_up' => lambda { $gtk.args.keyboard.key_up },
+ 'state' => lambda { $gtk.args.state },
+ '$gtk' => lambda { $gtk }
+ }
+
+ lookup_result = lookup[dot]
+
+ return autocomplete_filter_methods lookup_result.call.autocomplete_methods if lookup_result
+
+ start_collecting = false
+ dots_after_state = dots.find_all do |s|
+ if s == "state"
+ start_collecting = true
+ false
+ else
+ start_collecting
+ end
+ end
+
+ target = $gtk.args.state
+ dots_after_state.each do |k|
+ target = target.as_hash[k.to_sym] if target.respond_to? :as_hash
+ end
+
+ return autocomplete_filter_methods target.as_hash.keys
+ end
+
+
+ text.gsub!("[", " ")
+ text.gsub!("]", " ")
+ text.gsub!("(", " ")
+ text.gsub!(")", " ")
+ text.gsub!(":", "")
+ text.gsub!(".", " ")
+ text.gsub!("=", " ")
+ return (autocomplete_filter_methods (text.split " "),
+ :gtk, :false, :true, :args, :suppress_mailbox, :end)
+ end
+ end # end Autocomplete
+ end # end Runtime
+end # end GTK
diff --git a/dragon/console.rb b/dragon/console.rb
index ddf0702..be476bd 100644
--- a/dragon/console.rb
+++ b/dragon/console.rb
@@ -569,7 +569,7 @@ S
end
def error_markers
- ["exception", "error", "undefined method", "failed", "syntax", "deprecated"]
+ ["exception:", "error:", "undefined method", "failed", "syntax", "deprecated"]
end
def include_subdued_markers? text
@@ -581,7 +581,7 @@ S
end
def subdued_markers
- ["reloaded", "exported the"]
+ ["reloaded", "exported the", "~require~"]
end
def calc args
diff --git a/dragon/draw.rb b/dragon/draw.rb
index ee91b09..0afea16 100644
--- a/dragon/draw.rb
+++ b/dragon/draw.rb
@@ -16,115 +16,131 @@ module GTK
# pass.solids.each { |s| draw_solid s }
# while loops are faster than each with block
idx = 0
+ length = pass.solids.length
while idx < pass.solids.length
- draw_solid (pass.solids.value idx) # accessing an array using .value instead of [] is faster
+ draw_solid (pass.solids.at idx) # accessing an array using .value instead of [] is faster
idx += 1
end
# pass.static_solids.each { |s| draw_solid s }
idx = 0
- while idx < pass.static_solids.length
- draw_solid (pass.static_solids.value idx)
+ length = pass.static_solids.length
+ while idx < length
+ draw_solid (pass.static_solids.at idx)
idx += 1
end
# pass.sprites.each { |s| draw_sprite s }
idx = 0
- while idx < pass.sprites.length
- draw_sprite (pass.sprites.value idx)
+ length = pass.sprites.length
+ while idx < length
+ draw_sprite (pass.sprites.at idx)
idx += 1
end
# pass.static_sprites.each { |s| draw_sprite s }
idx = 0
- while idx < pass.static_sprites.length
- draw_sprite (pass.static_sprites.value idx)
+ length = pass.static_sprites.length
+ while idx < length
+ draw_sprite (pass.static_sprites.at idx)
idx += 1
end
# pass.primitives.each { |p| draw_primitive p }
idx = 0
- while idx < pass.primitives.length
- draw_primitive (pass.primitives.value idx)
+ length = pass.primitives.length
+ while idx < length
+ draw_primitive (pass.primitives.at idx)
idx += 1
end
# pass.static_primitives.each { |p| draw_primitive p }
idx = 0
- while idx < pass.static_primitives.length
- draw_primitive (pass.static_primitives.value idx)
+ length = pass.static_primitives.length
+ while idx < length
+ draw_primitive (pass.static_primitives.at idx)
idx += 1
end
# pass.labels.each { |l| draw_label l }
idx = 0
- while idx < pass.labels.length
- draw_label (pass.labels.value idx)
+ length = pass.labels.length
+ while idx < length
+ draw_label (pass.labels.at idx)
idx += 1
end
# pass.static_labels.each { |l| draw_label l }
idx = 0
- while idx < pass.static_labels.length
- draw_label (pass.static_labels.value idx)
+ length = pass.static_labels.length
+ while idx < length
+ draw_label (pass.static_labels.at idx)
idx += 1
end
# pass.lines.each { |l| draw_line l }
idx = 0
- while idx < pass.lines.length
- draw_line (pass.lines.value idx)
+ length = pass.lines.length
+ while idx < length
+ draw_line (pass.lines.at idx)
idx += 1
end
# pass.static_lines.each { |l| draw_line l }
idx = 0
+ length = pass.static_lines.length
while idx < pass.static_lines.length
- draw_line (pass.static_lines.value idx)
+ draw_line (pass.static_lines.at idx)
idx += 1
end
# pass.borders.each { |b| draw_border b }
idx = 0
- while idx < pass.borders.length
- draw_border (pass.borders.value idx)
+ length = pass.borders.length
+ while idx < length
+ draw_border (pass.borders.at idx)
idx += 1
end
# pass.static_borders.each { |b| draw_border b }
idx = 0
- while idx < pass.static_borders.length
- draw_border (pass.static_borders.value idx)
+ length = pass.static_borders.length
+ while idx < length
+ draw_border (pass.static_borders.at idx)
idx += 1
end
if !$gtk.production
# pass.debug.each { |r| draw_primitive r }
idx = 0
- while idx < pass.debug.length
- draw_primitive (pass.debug.value idx)
+ length = pass.debug.length
+ while idx < length
+ draw_primitive (pass.debug.at idx)
idx += 1
end
# pass.static_debug.each { |r| draw_primitive r }
idx = 0
- while idx < pass.static_debug.length
- draw_primitive (pass.static_debug.value idx)
+ length = pass.static_debug.length
+ while idx < length
+ draw_primitive (pass.static_debug.at idx)
idx += 1
end
end
# pass.reserved.each { |r| draw_primitive r }
idx = 0
- while idx < pass.reserved.length
- draw_primitive (pass.reserved.value idx)
+ length = pass.reserved.length
+ while idx < length
+ draw_primitive (pass.reserved.at idx)
idx += 1
end
# pass.static_reserved.each { |r| draw_primitive r }
idx = 0
- while idx < pass.static_reserved.length
- draw_primitive (pass.static_reserved.value idx)
+ length = pass.static_reserved.length
+ while idx < length
+ draw_primitive (pass.static_reserved.at idx)
idx += 1
end
rescue Exception => e
diff --git a/dragon/easing.rb b/dragon/easing.rb
index 310e7ed..f503132 100644
--- a/dragon/easing.rb
+++ b/dragon/easing.rb
@@ -31,12 +31,12 @@ module GTK
def self.initial_value *definitions
definitions.flatten!
- return Easing.exec_definition (definitions.value(-1) || :identity), 0, 10, 0
+ return Easing.exec_definition (definitions.at(-1) || :identity), 0, 10, 0
end
def self.final_value *definitions
definitions.flatten!
- return Easing.exec_definition (definitions.value(-1) || :identity), 0, 10, 1.0
+ return Easing.exec_definition (definitions.at(-1) || :identity), 0, 10, 1.0
end
def self.exec_definition definition, start_tick, duration, x
diff --git a/dragon/framerate.rb b/dragon/framerate.rb
new file mode 100644
index 0000000..2550443
--- /dev/null
+++ b/dragon/framerate.rb
@@ -0,0 +1,83 @@
+# Copyright 2019 DragonRuby LLC
+# MIT License
+# framerate.rb has been released under MIT (*only this file*).
+
+module GTK
+ class Runtime
+ module Framerate
+ def framerate_init
+ @tick_time = Time.new.to_i
+ end
+
+ def delta_framerate
+ (current_framerate || 0) - (@previous_framerate || 0)
+ end
+
+ def reset_framerate_calculation
+ @tick_speed_sum = 0
+ @tick_speed_count = 0
+ @previous_framerate = 0
+ end
+
+ def check_framerate
+ if @framerate_diagnostics_requested
+ log "================================"
+ log framerate_get_diagnostics
+ @framerate_diagnostics_requested = false
+ end
+
+ if !@paused
+ if @tick_time
+ @tick_speed_count += 1
+ @tick_speed_sum += Time.now.to_i - @tick_time
+ if @tick_speed_count > 60 * 2
+ if framerate_below_threshold?
+ @last_framerate = current_framerate
+ if !@framerate_important_notification_happened
+ log_important framerate_warning_message
+ else
+ log framerate_warning_message
+ end
+ @framerate_important_notification_happened = true
+ end
+ end
+
+ @previous_framerate = current_framerate.floor
+ end
+ end
+
+ @tick_time = Time.new.to_i
+ else
+ reset_framerate_calculation
+ end
+ rescue
+ reset_framerate_calculation
+ end
+
+ def framerate_diagnostics
+ # request framerate diagnostics to be printed at the end of tick
+ @framerate_diagnostics_requested = true
+ end
+
+ def framerate_below_threshold?
+ @last_framerate ||= 60
+ current_framerate < @last_framerate &&
+ current_framerate < 50 &&
+ @previous_framerate > current_framerate &&
+ Kernel.tick_count > 600
+ end
+
+ def current_framerate
+ return 60 if !@tick_speed_sum || !@tick_speed_sum
+ r = 100.fdiv(@tick_speed_sum.fdiv(@tick_speed_count) * 100)
+ if (r.nan? || r.infinite? || r > 58)
+ r = 60
+ end
+ r || 60
+ rescue
+ 60
+ end
+ end # module Framerate
+ end # end class Runtime
+end # end module GTK
diff --git a/dragon/framerate_diagnostics.rb b/dragon/framerate_diagnostics.rb
index 7a04efc..4586472 100644
--- a/dragon/framerate_diagnostics.rb
+++ b/dragon/framerate_diagnostics.rb
@@ -4,7 +4,6 @@
module GTK
class Runtime
- # @visibility private
module FramerateDiagnostics
def framerate_get_diagnostics
<<-S
diff --git a/dragon/geometry.rb b/dragon/geometry.rb
index db3ebfc..9385022 100644
--- a/dragon/geometry.rb
+++ b/dragon/geometry.rb
@@ -76,10 +76,10 @@ module GTK
Geometry.point_inside_circle? self, circle_center_point, radius
end
- def center_inside_rect other_rect
- offset_x = (other_rect.w - w).half
- offset_y = (other_rect.h - h).half
- new_rect = self.shift_rect(0, 0)
+ def self.center_inside_rect rect, other_rect
+ offset_x = (other_rect.w - rect.w).half
+ offset_y = (other_rect.h - rect.h).half
+ new_rect = rect.shift_rect(0, 0)
new_rect.x = other_rect.x + offset_x
new_rect.y = other_rect.y + offset_y
new_rect
@@ -90,30 +90,45 @@ center_inside_rect for self #{self} and other_rect #{other_rect}. Failed with ex
S
end
- def center_inside_rect_y other_rect
- offset_y = (other_rect.h - h).half
- new_rect = self.shift_rect(0, 0)
- new_rect.y = other_rect.y + offset_y
+ def center_inside_rect other_rect
+ Geometry.center_inside_rect self, other_rect
+ end
+
+ def self.center_inside_rect_x rect, other_rect
+ offset_x = (other_rect.w - rect.w).half
+ new_rect = rect.shift_rect(0, 0)
+ new_rect.x = other_rect.x + offset_x
+ new_rect.y = other_rect.y
new_rect
rescue Exception => e
raise e, <<-S
* ERROR:
-center_inside_rect_y for self #{self} and other_rect #{other_rect}. Failed with exception #{e}.
+center_inside_rect_x for self #{self} and other_rect #{other_rect}. Failed with exception #{e}.
S
end
def center_inside_rect_x other_rect
- offset_x = (other_rect.w - w).half
- new_rect = self.shift_rect(0, 0)
- new_rect.x = other_rect.x + offset_x
+ Geometry.center_inside_rect_x self, other_rect
+ end
+
+ def self.center_inside_rect_y rect, other_rect
+ offset_y = (other_rect.h - rect.h).half
+ new_rect = rect.shift_rect(0, 0)
+ new_rect.x = other_rect.x
+ new_rect.y = other_rect.y + offset_y
new_rect
rescue Exception => e
raise e, <<-S
* ERROR:
-center_inside_rect_x for self #{self} and other_rect #{other_rect}. Failed with exception #{e}.
+center_inside_rect_y for self #{self} and other_rect #{other_rect}. Failed with exception #{e}.
S
end
+ def center_inside_rect_y other_rect
+ Geometry.center_inside_rect_y self, other_rect
+ end
+
+
# Returns a primitive that is anchored/repositioned based off its retangle.
# @gtk
def anchor_rect anchor_x, anchor_y
@@ -170,10 +185,27 @@ S
# @gtk
def self.line_slope line, replace_infinity: nil
+ return replace_infinity if line.x2 == line.x
(line.y2 - line.y).fdiv(line.x2 - line.x)
.replace_infinity(replace_infinity)
end
+ def self.line_rise_run line
+ rise = (line.y2 - line.y).to_f
+ run = (line.x2 - line.x).to_f
+ if rise.abs > run.abs && rise != 0
+ rise = rise.fdiv rise.abs
+ run = run.fdiv rise.abs
+ elsif run.abs > rise.abs && run != 0
+ rise = rise.fdiv run.abs
+ run = run.fdiv run.abs
+ else
+ rise = rise / rise.abs if rise != 0
+ run = run / run.abs if run != 0
+ end
+ return { x: run , y: rise }
+ end
+
# @gtk
def self.ray_test point, line
slope = (line.y2 - line.y).fdiv(line.x2 - line.x)
@@ -239,8 +271,8 @@ S
return false if rect_one.bottom + tolerance > rect_two.top - tolerance
return true
rescue Exception => e
- context_help_rect_one = (rect_one.help_contract_implementation contract_intersect_rect?)[:not_implemented_methods]
- context_help_rect_two = (rect_two.help_contract_implementation contract_intersect_rect?)[:not_implemented_methods]
+ context_help_rect_one = (rect_one.__help_contract_implementation contract_intersect_rect?)[:not_implemented_methods]
+ context_help_rect_two = (rect_two.__help_contract_implementation contract_intersect_rect?)[:not_implemented_methods]
context_help = ""
if context_help_rect_one && context_help_rect_one.length > 0
context_help += <<-S
diff --git a/dragon/inputs.rb b/dragon/inputs.rb
index 13cfe06..5d1727b 100644
--- a/dragon/inputs.rb
+++ b/dragon/inputs.rb
@@ -525,6 +525,10 @@ module GTK
point.point_inside_circle? center, radius
end
+ def intersect_rect? other_rect
+ { x: point.x, y: point.y, w: 0, h: 0 }.intersect_rect? other_rect
+ end
+
alias_method :position, :point
def clear
@@ -583,6 +587,7 @@ module GTK
:moved_at,
:global_moved_at,
:touch_order,
+ :first_tick_down,
:x, :y
def initialize
@@ -590,6 +595,7 @@ module GTK
@moved_at = 0
@global_moved_at = 0
@touch_order = 0
+ @first_tick_down = true
@x = 0
@y = 0
end
diff --git a/dragon/ios_wizard.rb b/dragon/ios_wizard.rb
index b3f170a..77fd703 100644
--- a/dragon/ios_wizard.rb
+++ b/dragon/ios_wizard.rb
@@ -85,6 +85,11 @@ class IOSWizard
return nil
end
+ def always_fail
+ return false if $gtk.ivar :rcb_release_mode
+ return true
+ end
+
def check_for_xcode
if !cli_app_exist?(xcodebuild_cli_app)
raise WizardException.new(
@@ -129,6 +134,11 @@ class IOSWizard
end
end
+ def restart
+ init_wizard_status
+ start
+ end
+
def check_for_dev_profile
@dev_profile_path = "profiles/development.mobileprovision"
if !($gtk.read_file @dev_profile_path)
@@ -182,6 +192,21 @@ class IOSWizard
log_info "App Identifier is set to : #{@app_id}"
end
+ def set_app_name name
+ @app_name = name
+ start
+ end
+
+ def set_dev_profile path
+ if !$gtk.read_file path
+ log_error "I couldn't find a development profile at #{path}."
+ ask_for_dev_profile
+ else
+ @dev_profile_path = path
+ start
+ end
+ end
+
def blow_away_temp
sh "rm -rf #{tmp_directory}"
end
@@ -192,6 +217,12 @@ class IOSWizard
sh "cp -R #{relative_path}/dragonruby-ios.app \"#{tmp_directory}/#{@app_name}.app\""
end
+ def set_app_id id
+ log_info = "App Id set to: #{id}"
+ @app_id = id
+ start
+ end
+
def check_for_device
log_info "Looking for device."
diff --git a/dragon/layout.rb b/dragon/layout.rb
index 915ac37..238193d 100644
--- a/dragon/layout.rb
+++ b/dragon/layout.rb
@@ -359,6 +359,13 @@ module GTK
result[:h] += device.grid_area.gutter * 2
end
+ result[:x] += opts[:dx] if opts[:dx]
+ result[:y] += opts[:dy] if opts[:dy]
+ result[:w] += opts[:dw] if opts[:dw]
+ result[:h] += opts[:dh] if opts[:dh]
+ result[:row] = opts[:row]
+ result[:col] = opts[:col]
+
result
end
diff --git a/dragon/numeric.rb b/dragon/numeric.rb
index 548e0e2..0ee1457 100644
--- a/dragon/numeric.rb
+++ b/dragon/numeric.rb
@@ -281,16 +281,18 @@ S
vector_y max_value
end
- # @gtk
def mod n
self % n
end
- # @gtk
def mod_zero? *ns
ns.any? { |n| mod(n) == 0 }
end
+ def zmod? n
+ (self % n) == 0
+ end
+
def mult n
self * n
end
@@ -592,6 +594,14 @@ class Fixnum
def sin
Math.sin(self.to_radians)
end
+
+ def to_sf
+ "%.2f" % self
+ end
+
+ def ifloor int
+ (self.idiv int.to_i) * int.to_i
+ end
end
class Float
@@ -638,6 +648,14 @@ class Float
return -scalar if self < 0
return scalar if self > 0
end
+
+ def to_sf
+ "%.2f" % self
+ end
+
+ def ifloor int
+ (self.idiv int.to_i) * int.to_i
+ end
end
class Integer
diff --git a/dragon/readme_docs.rb b/dragon/readme_docs.rb
index 6ac336f..0b5e1a1 100644
--- a/dragon/readme_docs.rb
+++ b/dragon/readme_docs.rb
@@ -509,35 +509,36 @@ specific approach to game development. Collaborate with us.
** Continuity of Design
-There is a programming idiom in software called "the pit of
-success". The term normalizes up front pain as a necessity in the
-(hopes that the investment will yield dividends "when you become
-successful"). This results in more "Enterprise TM" code upfront, and
-makes it more difficult to get started when you are new to programming.
-
-DragonRuby's philosophy is to provide a spectrum across the "make it
-fast" vs "make it right" spectrum and provide incremental, intuitive
-transitions between points on that spectrum. This is captured in how
-render primitives can be represented as tuples/arrays, hashes, open
-structs/entities, and then finally classes (as opposed to forcing devs
-to use classes upfront).
-
-** Release Often And Soon
+There is a programming idiom in software called "The Pit of
+Success". The term normalizes upfront pain as a necessity/requirement in the
+hopes that the investment will yield dividends "when you become
+successful" or "when the code becomes more complicated". This approach to
+development is strongly discouraged by us. It leads to over-architected
+and unnessary code; creates barriers to rapid prototyping and shipping a game; and
+overwhelms beginners who are new to the engine or programming in general.
+
+DragonRuby's philosophy is to provide multiple options across the "make it
+fast" vs "make it right" spectrum, with incremental/intuitive
+transitions between the options provided. A concrete example of this philosophy
+would be render primitives: the spectrum of options allows renderable constructs take
+the form of tuples/arrays (easy to pickup, simple, and fast to code/prototype with),
+hashes (a little more work, but gives you the ability to add additional properties),
+open and string entities (more work than hashes, but yields cleaner apis),
+and finally - if you really need full power/flexibility in rendering - classes
+(which take the most amount of code and programming knowledge to create).
+
+** Release Early and Often
The biggest mistake game devs make is spending too much time in
isolation building their game. Release something, however small, and
-release it quickly.
+release it soon.
Stop worrying about everything being pixel perfect. Don't wait until
your game is 100% complete. Build your game publicly and
iterate. Post in the #show-and-tell channel in the community Discord.
You'll find a lot of support and encouragement there.
-Remember:
-
-#+begin_quote
-Real artists ship.
-#+end_quote
+Real artists ship. Remember that.
** Sustainable And Ethical Monetization
@@ -549,6 +550,10 @@ Charge a fair amount of money for the things you create. It's expected
and encouraged within the community. Give what you create away for
free to those that can't afford it.
+If you are gainfully employed, pay full price for the things you use. If you
+do end up getting something at a discount, pay the differnce "forward" to
+someone else.
+
** Sustainable And Ethical Open Source
This goes hand in hand with sustainable and ethical monetization. The