gamefic 1.7.0 → 2.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.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +13 -0
  5. data/.solargraph.yml +5 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE +20 -0
  8. data/README.md +28 -0
  9. data/Rakefile +10 -0
  10. data/gamefic.gemspec +27 -0
  11. data/lib/gamefic.rb +7 -6
  12. data/lib/gamefic/action.rb +38 -28
  13. data/lib/gamefic/active.rb +325 -280
  14. data/lib/gamefic/actor.rb +8 -5
  15. data/lib/gamefic/command.rb +9 -7
  16. data/lib/gamefic/core_ext/array.rb +24 -49
  17. data/lib/gamefic/core_ext/string.rb +25 -16
  18. data/lib/gamefic/describable.rb +21 -23
  19. data/lib/gamefic/element.rb +43 -31
  20. data/lib/gamefic/entity.rb +6 -12
  21. data/lib/gamefic/index.rb +121 -0
  22. data/lib/gamefic/{matchable.rb → keywords.rb} +52 -50
  23. data/lib/gamefic/messaging.rb +43 -44
  24. data/lib/gamefic/node.rb +14 -5
  25. data/lib/gamefic/plot.rb +69 -89
  26. data/lib/gamefic/plot/darkroom.rb +92 -264
  27. data/lib/gamefic/plot/host.rb +42 -48
  28. data/lib/gamefic/plot/snapshot.rb +5 -18
  29. data/lib/gamefic/query.rb +14 -18
  30. data/lib/gamefic/query/base.rb +30 -18
  31. data/lib/gamefic/query/children.rb +0 -0
  32. data/lib/gamefic/query/external.rb +18 -14
  33. data/lib/gamefic/query/family.rb +1 -7
  34. data/lib/gamefic/query/matches.rb +75 -67
  35. data/lib/gamefic/query/parent.rb +0 -0
  36. data/lib/gamefic/query/siblings.rb +0 -0
  37. data/lib/gamefic/query/text.rb +2 -1
  38. data/lib/gamefic/scene.rb +0 -2
  39. data/lib/gamefic/scene/activity.rb +24 -26
  40. data/lib/gamefic/scene/base.rb +64 -8
  41. data/lib/gamefic/scene/conclusion.rb +0 -2
  42. data/lib/gamefic/scene/custom.rb +0 -2
  43. data/lib/gamefic/scene/multiple_choice.rb +18 -3
  44. data/lib/gamefic/scene/multiple_scene.rb +29 -20
  45. data/lib/gamefic/scene/pause.rb +7 -2
  46. data/lib/gamefic/scene/yes_or_no.rb +21 -9
  47. data/lib/gamefic/scriptable.rb +87 -0
  48. data/lib/gamefic/serialize.rb +68 -0
  49. data/lib/gamefic/subplot.rb +29 -35
  50. data/lib/gamefic/syntax.rb +14 -13
  51. data/lib/gamefic/version.rb +3 -3
  52. data/lib/gamefic/world.rb +16 -0
  53. data/lib/gamefic/world/callbacks.rb +135 -0
  54. data/lib/gamefic/world/commands.rb +184 -0
  55. data/lib/gamefic/{plot → world}/entities.rb +30 -29
  56. data/lib/gamefic/{plot → world}/playbook.rb +255 -240
  57. data/lib/gamefic/world/players.rb +21 -0
  58. data/lib/gamefic/world/scenes.rb +226 -0
  59. metadata +41 -92
  60. data/bin/gamefic +0 -9
  61. data/lib/gamefic/engine.rb +0 -7
  62. data/lib/gamefic/engine/base.rb +0 -59
  63. data/lib/gamefic/engine/tty.rb +0 -24
  64. data/lib/gamefic/grammar.rb +0 -13
  65. data/lib/gamefic/grammar/conjugator.rb +0 -20
  66. data/lib/gamefic/grammar/gender.rb +0 -11
  67. data/lib/gamefic/grammar/person.rb +0 -10
  68. data/lib/gamefic/grammar/plural.rb +0 -13
  69. data/lib/gamefic/grammar/pronouns.rb +0 -106
  70. data/lib/gamefic/grammar/tense.rb +0 -6
  71. data/lib/gamefic/grammar/verb_set.rb +0 -43
  72. data/lib/gamefic/grammar/verbs.rb +0 -26
  73. data/lib/gamefic/grammar/word_adapter.rb +0 -49
  74. data/lib/gamefic/plot/articles.rb +0 -22
  75. data/lib/gamefic/plot/callbacks.rb +0 -126
  76. data/lib/gamefic/plot/commands.rb +0 -120
  77. data/lib/gamefic/plot/players.rb +0 -15
  78. data/lib/gamefic/plot/scenes.rb +0 -187
  79. data/lib/gamefic/plot/theater.rb +0 -73
  80. data/lib/gamefic/plot/you_mount.rb +0 -22
  81. data/lib/gamefic/script.rb +0 -13
  82. data/lib/gamefic/script/base.rb +0 -42
  83. data/lib/gamefic/script/file.rb +0 -14
  84. data/lib/gamefic/script/text.rb +0 -14
  85. data/lib/gamefic/shell.rb +0 -76
  86. data/lib/gamefic/source.rb +0 -14
  87. data/lib/gamefic/source/base.rb +0 -12
  88. data/lib/gamefic/source/file.rb +0 -23
  89. data/lib/gamefic/source/text.rb +0 -16
  90. data/lib/gamefic/tester.rb +0 -19
  91. data/lib/gamefic/text.rb +0 -8
  92. data/lib/gamefic/text/ansi.rb +0 -53
  93. data/lib/gamefic/text/html.rb +0 -68
  94. data/lib/gamefic/text/html/conversions.rb +0 -250
  95. data/lib/gamefic/text/html/entities.rb +0 -9
  96. data/lib/gamefic/tty.rb +0 -10
  97. data/lib/gamefic/user.rb +0 -7
  98. data/lib/gamefic/user/base.rb +0 -29
  99. data/lib/gamefic/user/tty.rb +0 -38
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'gamefic'
4
- require 'gamefic/shell'
5
-
6
- # Make play the default command if the first argument is an existing file
7
- args = %w(play help).include?(ARGV[0]) || ARGV.count.zero? || !File.exist?(ARGV[0]) ? ARGV : ARGV.dup.unshift('play')
8
-
9
- Gamefic::Shell.start(args)
@@ -1,7 +0,0 @@
1
- module Gamefic
2
-
3
- module Engine
4
- autoload :Base, 'gamefic/engine/base'
5
- end
6
-
7
- end
@@ -1,59 +0,0 @@
1
- module Gamefic
2
-
3
- # Basic functionality for running a single-player game from a console.
4
- #
5
- class Engine::Base
6
- # @return [Class]
7
- attr_writer :user_class
8
-
9
- # @return [Gamefic::Plot]
10
- attr_reader :plot
11
-
12
- def initialize(plot)
13
- @plot = plot
14
- post_initialize
15
- end
16
-
17
- def post_initialize
18
- # Override in subclasses
19
- end
20
-
21
- def user_class
22
- @user_class ||= Gamefic::User::Base
23
- end
24
-
25
- def connect
26
- raise 'Plot did not specify a player class' if @plot.player_class.nil?
27
- # @todo The plot itself can define name, etc.
28
- character = @plot.make @plot.player_class, name: 'yourself', synonyms: 'self myself you me', proper_named: true
29
- @user = user_class.new(self)
30
- @user.connect character
31
- character.connect @user
32
- end
33
-
34
- def run
35
- connect
36
- @plot.introduce @user.character
37
- #@user.update @character.state
38
- turn until @user.character.concluded?
39
- @user.update
40
- #print @user.flush
41
- end
42
-
43
- def turn
44
- @plot.ready
45
- @user.update
46
- if @user.character.queue.empty?
47
- receive
48
- end
49
- @plot.update
50
- end
51
-
52
- def receive
53
- print @user.character.scene.prompt + ' '
54
- input = STDIN.gets
55
- @user.character.queue.push input unless input.nil?
56
- end
57
- end
58
-
59
- end
@@ -1,24 +0,0 @@
1
- require 'gamefic/user/tty'
2
-
3
- module Gamefic
4
-
5
- # Extend Engine::Base to connect with User::Tty, which provides ANSI
6
- # formatting for HTML.
7
- #
8
- # @note Due to their dependency on io/console, User::Tty and Engine::Tty are
9
- # not included in the core Gamefic library. `require gamefic/tty` if you
10
- # need them.
11
- #
12
- class Engine::Tty < Engine::Base
13
- def post_initialize
14
- self.user_class = Gamefic::User::Tty
15
- end
16
-
17
- def self.start plot
18
- engine = self.new(plot)
19
- engine.connect
20
- engine.run
21
- end
22
- end
23
-
24
- end
@@ -1,13 +0,0 @@
1
- module Gamefic
2
- module Grammar
3
- autoload :Tense, 'gamefic/grammar/tense'
4
- autoload :Pronouns, 'gamefic/grammar/pronouns'
5
- autoload :Conjugator, 'gamefic/grammar/conjugator'
6
- autoload :Verbs, 'gamefic/grammar/verbs'
7
- autoload :VerbSet, 'gamefic/grammar/verb_set'
8
- autoload :Person, 'gamefic/grammar/person'
9
- autoload :Plural, 'gamefic/grammar/plural'
10
- autoload :Gender, 'gamefic/grammar/gender'
11
- autoload :WordAdapter, 'gamefic/grammar/word_adapter'
12
- end
13
- end
@@ -1,20 +0,0 @@
1
- require 'gamefic'
2
- require 'gamefic/grammar'
3
-
4
- module Gamefic::Grammar
5
- module Conjugator
6
- module ClassMethods
7
- @@conjugated_verbs = {}
8
- def conjugate infinitive, tense, *forms
9
- @@conjugated_verbs[infinitive] ||= {}
10
- @@conjugated_verbs[infinitive][tense] = VerbSet.new(infinitive, *forms)
11
- end
12
- def conjugated_verbs
13
- @@conjugated_verbs
14
- end
15
- end
16
- #def self.included(base)
17
- # base.extend ClassMethods
18
- #end
19
- end
20
- end
@@ -1,11 +0,0 @@
1
- require 'gamefic/grammar'
2
-
3
- module Gamefic::Grammar
4
- module Gender
5
- attr_writer :gender
6
- def gender
7
- # Supported values are "male", "female", "other", and "neutral"
8
- @gender ||= "neutral"
9
- end
10
- end
11
- end
@@ -1,10 +0,0 @@
1
- require 'gamefic/grammar'
2
-
3
- module Gamefic::Grammar
4
- module Person
5
- attr_writer :person
6
- def person
7
- @person ||= 3
8
- end
9
- end
10
- end
@@ -1,13 +0,0 @@
1
- require 'gamefic/grammar'
2
-
3
- module Gamefic::Grammar
4
- module Plural
5
- attr_writer :plural
6
- def plural?
7
- if @plural.nil?
8
- @plural = false
9
- end
10
- @plural
11
- end
12
- end
13
- end
@@ -1,106 +0,0 @@
1
- require 'gamefic'
2
- require 'gamefic/grammar'
3
-
4
- module Gamefic::Grammar
5
- class Pronouns
6
- def initialize object
7
- @object = object
8
- end
9
-
10
- # Get the subjective pronoun (I, you, we, etc.)
11
- #
12
- # @return [String]
13
- def subj
14
- Pronouns.get_pronoun_set(@object)[0]
15
- end
16
-
17
- # Get the objective pronoun (me, them, us, etc.)
18
- #
19
- # @return [String]
20
- def obj
21
- Pronouns.get_pronoun_set(@object)[1]
22
- end
23
-
24
- # Get the possessive pronoun (my, your, our, etc.)
25
- #
26
- # @return [String]
27
- def poss
28
- Pronouns.get_pronoun_set(@object)[2]
29
- end
30
-
31
- # Get the reflexive pronoun (myself, yourself, etc.)
32
- #
33
- # @return [String]
34
- def reflex
35
- Pronouns.get_pronoun_set(@object)[3]
36
- end
37
-
38
- # Get the capitalized subjective pronoun
39
- #
40
- # @return [String]
41
- def Subj
42
- subj.cap_first
43
- end
44
-
45
- # Get the capitalized objective pronoun
46
- #
47
- # @return [String]
48
- def Obj
49
- obj.cap_first
50
- end
51
-
52
- # Get the capitalized possessive pronoun
53
- #
54
- # @return [String]
55
- def Poss
56
- poss.cap_first
57
- end
58
-
59
- # Get the capitalized reflexive pronoun
60
- #
61
- # @return [String]
62
- def Reflex
63
- reflex.cap_first
64
- end
65
-
66
- # Get a an array of pronouns based on the person, gender, and plurality of
67
- # the provided object.
68
- #
69
- # @param obj An object that responds to #person, #gender, and #plural
70
- # @return [Array<String>]
71
- def self.get_pronoun_set(obj)
72
- set = Pronouns.sets["#{obj.person}"]
73
- if set.nil?
74
- set = Pronouns.sets["#{obj.person}:#{obj.plural? ? 'plural' : 'singular'}"]
75
- end
76
- if set.nil?
77
- set = Pronouns.sets["#{obj.person}:#{obj.plural? ? 'plural' : 'singular'}:#{obj.gender}"]
78
- end
79
- if set.nil?
80
- raise "Pronoun set could not be determined"
81
- end
82
- set
83
- end
84
-
85
- # TODO Consider implementing method_missing to determine correct pronoun
86
- # from example, e.g., "he" would change to "she" for female entities
87
- def self.sets
88
- if @sets.nil?
89
- @sets = {}
90
- @sets["1:singular"] = ["I", "me", "my", "myself"]
91
- @sets["2:singular"] = ["you", "you", "your", "yourself"]
92
- @sets["3:singular:male"] = ["he", "him", "his", "himself"]
93
- @sets["3:singular:female"] = ["she", "her", "her", "herself"]
94
- # "other" refers to a person or living being that is neither
95
- # male or female or for whom gender is unspecified. It's
96
- # typically used to avoid referring to a person as "it."
97
- @sets["3:singular:other"] = ["they", "them", "their", "themselves"]
98
- @sets["3:singular:neutral"] = ["it", "it", "its", "itself"]
99
- @sets["1:plural"] = ["we", "us", "our", "ourselves"]
100
- @sets["2:plural"] = ["you", "you", "your", "yourselves"]
101
- @sets["3:plural"] = ["they", "them", "their", "themselves"]
102
- end
103
- @sets
104
- end
105
- end
106
- end
@@ -1,6 +0,0 @@
1
- require 'gamefic/grammar'
2
-
3
- module Gamefic::Grammar::Tense
4
- PRESENT = :present
5
- PAST = :past
6
- end
@@ -1,43 +0,0 @@
1
- require 'gamefic/grammar'
2
-
3
- module Gamefic::Grammar
4
- class VerbSet
5
- def initialize infinitive, *forms
6
- # TODO what to do with the tense?
7
- @infinitive = infinitive.to_s
8
- @forms = {}
9
- form = forms[0]
10
- @forms["1:singular"] = form.nil? ? @infinitive.to_s : form.to_s
11
- form = forms[1]
12
- @forms["2:singular"] = form.nil? ? @infinitive.to_s : form.to_s
13
- form = forms[2]
14
- @forms["3:singular"] = form.nil? ? generate_third_singular : form.to_s
15
- form = forms[3]
16
- @forms["1:plural"] = form.nil? ? @infinitive.to_s : form.to_s
17
- form = forms[4]
18
- @forms["2:plural"] = form.nil? ? @forms["1:plural"] : form.to_s
19
- form = forms[5]
20
- @forms["3:plural"] = form.nil? ? @forms["1:plural"] : form.to_s
21
- end
22
- def conjugate pronoun
23
- form = @forms["#{pronoun.person}"]
24
- if form.nil?
25
- form = @forms["#{pronoun.person}:#{pronoun.plural? ? 'plural' : 'singular'}"]
26
- end
27
- if form.nil?
28
- raise "Unable to conjugate #{@infinitive}"
29
- end
30
- form
31
- end
32
- private
33
- def generate_third_singular
34
- if @infinitive.end_with?('o')
35
- @infinitive + "es"
36
- elsif @infinitive.end_with?('ry')
37
- @infinitive[0..-2] + "ies"
38
- else
39
- @infinitive + "s"
40
- end
41
- end
42
- end
43
- end
@@ -1,26 +0,0 @@
1
- require 'gamefic'
2
- require 'gamefic/grammar'
3
-
4
- module Gamefic::Grammar
5
- class Verbs
6
- extend Gamefic::Grammar::Conjugator::ClassMethods
7
- def initialize obj
8
- @pronoun = obj
9
- self.class.conjugated_verbs.each_pair { |infinitive, verbset|
10
- define_singleton_method infinitive do
11
- verbset[:present].conjugate @pronoun
12
- end
13
- }
14
- end
15
- def method_missing infinitive, *args, &block
16
- Gamefic::Grammar::VerbSet.new(infinitive, nil, *args).conjugate(@pronoun)
17
- end
18
- def [] infinitive
19
- words = infinitive.split_words
20
- Gamefic::Grammar::VerbSet.new(words[0], nil).conjugate(@pronoun) + (words.length > 1 ? ' ' + words[1..-1].join(' ') : '')
21
- end
22
- conjugate :be, :present, :am, :are, :is, :are
23
- conjugate :have, :present, :have, :have, :has, :have
24
- conjugate :can, :present, :can, :can, :can
25
- end
26
- end
@@ -1,49 +0,0 @@
1
- require 'gamefic/grammar'
2
- require 'gamefic/grammar/gender'
3
-
4
- module Gamefic::Grammar
5
- module WordAdapter
6
- include Gender
7
- include Person
8
- include Plural
9
- # @return [Gamefic::Grammar::Pronouns]
10
- def pronoun
11
- @pronoun ||= Gamefic::Grammar::Pronouns.new(self)
12
- end
13
- # @return [Gamefic::Grammar::Verbs]
14
- def verb
15
- @verb ||= Gamefic::Grammar::Verbs.new(self)
16
- end
17
- def contract words
18
- contractions[words] || words
19
- end
20
- private
21
- def contractions
22
- if @contractions.nil?
23
- @contractions ||= {
24
- "I am" => "I'm",
25
- "you are" => "you're",
26
- "he is" => "he's",
27
- "she is" => "she's",
28
- "it is" => "it's",
29
- "we are" => "we're",
30
- "they are" => "they're",
31
- "am not" => "am not",
32
- "are not" => "aren't",
33
- "is not" => "isn't",
34
- "do not" => "don't",
35
- "does not" => "doesn't",
36
- "can not" => "can't"
37
- }
38
- capitalized = {}
39
- @contractions.each_pair { |k,v |
40
- if k[0] != k[0].capitalize
41
- capitalized[k.cap_first] = v.cap_first
42
- end
43
- }
44
- @contractions.merge! capitalized
45
- end
46
- @contractions
47
- end
48
- end
49
- end
@@ -1,22 +0,0 @@
1
- module Gamefic
2
- module Plot::Articles
3
- def a(entity)
4
- entity.indefinitely
5
- end
6
- def an(entity)
7
- entity.indefinitely
8
- end
9
- def the(entity)
10
- entity.definitely
11
- end
12
- def A(entity)
13
- entity.indefinitely.cap_first
14
- end
15
- def An(entity)
16
- entity.indefinitely.cap_first
17
- end
18
- def The(entity)
19
- entity.definitely.cap_first
20
- end
21
- end
22
- end
@@ -1,126 +0,0 @@
1
- module Gamefic
2
-
3
- module Plot::Callbacks
4
- # Add a block to be executed on preparation of every turn.
5
- #
6
- # @example Increment a turn counter
7
- # turn = 0
8
- # on_ready do
9
- # turn += 1
10
- # end
11
- #
12
- def on_ready &block
13
- p_ready_procs.push block
14
- end
15
-
16
- # Add a block to be executed after the Plot is finished updating a turn.
17
- #
18
- def on_update &block
19
- p_update_procs.push block
20
- end
21
-
22
- # Add a block to be executed for each player at the beginning of a turn.
23
- #
24
- # @example Tell the player how many turns they've played.
25
- # on_player_ready do |player|
26
- # player[:turns] ||= 0
27
- # if player[:turns] > 0
28
- # player.tell "Turn #{player[:turns]}"
29
- # end
30
- # player[:turns] += 1
31
- # end
32
- #
33
- # @yieldparam [Gamefic::Performance]
34
- def on_player_ready &block
35
- p_player_ready_procs.push block
36
- end
37
-
38
- # Add a block to be executed for each player before an update.
39
- #
40
- # @yieldparam[Character]
41
- def before_player_update &block
42
- p_before_player_update_procs.push block
43
- end
44
-
45
- # Add a block to be executed for each player at the end of a turn.
46
- #
47
- # @yieldparam [Character]
48
- def on_player_update &block
49
- p_player_update_procs.push block
50
- end
51
-
52
- private
53
-
54
- # Execute the on_ready blocks. This method is typically called by the
55
- # Plot while beginning a turn.
56
- #
57
- def call_ready
58
- p_ready_procs.each { |p| p.call }
59
- end
60
-
61
- # Execute the on_update blocks. This method is typically called by the
62
- # Plot while ending a turn.
63
- #
64
- def call_update
65
- p_update_procs.each { |p| p.call }
66
- end
67
-
68
- # Execute the before_player_update blocks for each player. This method is
69
- # typically called by the Plot while updating a turn, immediately before
70
- # processing player input.
71
- #
72
- def call_before_player_update
73
- p_players.each { |player|
74
- player.flush
75
- p_before_player_update_procs.each { |block| block.call player }
76
- }
77
- end
78
-
79
- # Execute the on_player_ready blocks for each player. This method is
80
- # typically called by the Plot while beginning a turn, immediately after
81
- # the on_ready blocks.
82
- #
83
- def call_player_ready
84
- p_players.each { |player|
85
- unless player.next_scene.nil?
86
- player.cue player.next_scene
87
- end
88
- player.cue default_scene if player.scene.nil?
89
- #player.prepare nil
90
- #player.cue this_scene #unless player.scene.class == this_scene
91
- p_player_ready_procs.each { |block| block.call player }
92
- }
93
- end
94
-
95
- # Execute the on_player_update blocks for each player. This method is
96
- # typically called by the Plot while ending a turn, immediately before the
97
- # on_ready blocks.
98
- #
99
- def call_player_update
100
- p_players.each { |player|
101
- p_player_update_procs.each { |block| block.call player }
102
- }
103
- end
104
-
105
- def p_ready_procs
106
- @p_ready_procs ||= []
107
- end
108
-
109
- def p_update_procs
110
- @p_update_procs ||= []
111
- end
112
-
113
- def p_before_player_update_procs
114
- @p_before_player_update_procs ||= []
115
- end
116
-
117
- def p_player_ready_procs
118
- @p_player_ready_procs ||= []
119
- end
120
-
121
- def p_player_update_procs
122
- @p_player_update_procs ||= []
123
- end
124
- end
125
-
126
- end