gamefic 1.5.1 → 1.6.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gamefic.rb +1 -3
  3. data/lib/gamefic/action.rb +140 -79
  4. data/lib/gamefic/character.rb +120 -53
  5. data/lib/gamefic/character/state.rb +12 -0
  6. data/lib/gamefic/core_ext/array.rb +53 -11
  7. data/lib/gamefic/core_ext/string.rb +1 -0
  8. data/lib/gamefic/describable.rb +37 -11
  9. data/lib/gamefic/engine/base.rb +17 -4
  10. data/lib/gamefic/engine/tty.rb +4 -0
  11. data/lib/gamefic/entity.rb +4 -15
  12. data/lib/gamefic/matchable.rb +50 -0
  13. data/lib/gamefic/messaging.rb +45 -0
  14. data/lib/gamefic/node.rb +16 -0
  15. data/lib/gamefic/plot.rb +27 -33
  16. data/lib/gamefic/plot/{article_mount.rb → articles.rb} +22 -22
  17. data/lib/gamefic/plot/callbacks.rb +30 -4
  18. data/lib/gamefic/plot/{command_mount.rb → commands.rb} +121 -121
  19. data/lib/gamefic/plot/entities.rb +3 -3
  20. data/lib/gamefic/plot/host.rb +3 -3
  21. data/lib/gamefic/plot/playbook.rb +74 -30
  22. data/lib/gamefic/plot/scenes.rb +149 -0
  23. data/lib/gamefic/plot/snapshot.rb +14 -39
  24. data/lib/gamefic/plot/theater.rb +73 -0
  25. data/lib/gamefic/query.rb +6 -19
  26. data/lib/gamefic/query/base.rb +127 -246
  27. data/lib/gamefic/query/children.rb +6 -7
  28. data/lib/gamefic/query/descendants.rb +15 -0
  29. data/lib/gamefic/query/family.rb +19 -7
  30. data/lib/gamefic/query/itself.rb +13 -0
  31. data/lib/gamefic/query/matches.rb +67 -11
  32. data/lib/gamefic/query/parent.rb +6 -7
  33. data/lib/gamefic/query/siblings.rb +10 -7
  34. data/lib/gamefic/query/text.rb +39 -35
  35. data/lib/gamefic/scene.rb +1 -1
  36. data/lib/gamefic/scene/active.rb +12 -6
  37. data/lib/gamefic/scene/base.rb +56 -5
  38. data/lib/gamefic/scene/conclusion.rb +3 -0
  39. data/lib/gamefic/scene/custom.rb +0 -83
  40. data/lib/gamefic/scene/multiple_choice.rb +54 -32
  41. data/lib/gamefic/scene/multiple_scene.rb +11 -6
  42. data/lib/gamefic/scene/pause.rb +3 -4
  43. data/lib/gamefic/scene/yes_or_no.rb +23 -9
  44. data/lib/gamefic/script/base.rb +4 -0
  45. data/lib/gamefic/subplot.rb +22 -19
  46. data/lib/gamefic/syntax.rb +7 -15
  47. data/lib/gamefic/user/base.rb +7 -13
  48. data/lib/gamefic/user/buffer.rb +7 -0
  49. data/lib/gamefic/user/tty.rb +13 -12
  50. data/lib/gamefic/version.rb +1 -1
  51. metadata +11 -37
  52. data/lib/gamefic/director.rb +0 -23
  53. data/lib/gamefic/director/delegate.rb +0 -126
  54. data/lib/gamefic/director/order.rb +0 -17
  55. data/lib/gamefic/director/parser.rb +0 -137
  56. data/lib/gamefic/keywords.rb +0 -67
  57. data/lib/gamefic/plot/query_mount.rb +0 -9
  58. data/lib/gamefic/plot/scene_mount.rb +0 -182
  59. data/lib/gamefic/query/ambiguous_children.rb +0 -5
  60. data/lib/gamefic/query/expression.rb +0 -47
  61. data/lib/gamefic/query/many_children.rb +0 -7
  62. data/lib/gamefic/query/plural_children.rb +0 -14
  63. data/lib/gamefic/query/self.rb +0 -10
  64. data/lib/gamefic/scene_data.rb +0 -10
  65. data/lib/gamefic/scene_data/base.rb +0 -12
  66. data/lib/gamefic/scene_data/multiple_choice.rb +0 -19
  67. data/lib/gamefic/scene_data/multiple_scene.rb +0 -21
  68. data/lib/gamefic/scene_data/yes_or_no.rb +0 -18
  69. data/lib/gamefic/serialized.rb +0 -24
  70. data/lib/gamefic/stage.rb +0 -106
data/lib/gamefic/plot.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # TODO: JSON support is currently experimental.
2
2
  #require 'gamefic/entityloader'
3
- require 'gamefic/stage'
4
3
  require 'gamefic/tester'
5
4
  require 'gamefic/source'
6
5
  require 'gamefic/script'
@@ -9,39 +8,37 @@ require 'gamefic/query'
9
8
  module Gamefic
10
9
 
11
10
  class Plot
12
- autoload :SceneMount, 'gamefic/plot/scene_mount'
13
- autoload :CommandMount, 'gamefic/plot/command_mount'
14
- autoload :Entities, 'gamefic/plot/entities'
15
- autoload :ArticleMount, 'gamefic/plot/article_mount'
16
- autoload :YouMount, 'gamefic/plot/you_mount'
17
- autoload :Snapshot, 'gamefic/plot/snapshot'
18
- autoload :Host, 'gamefic/plot/host'
19
- autoload :Players, 'gamefic/plot/players'
20
- autoload :Playbook, 'gamefic/plot/playbook'
21
- autoload :Callbacks, 'gamefic/plot/callbacks'
11
+ autoload :Scenes, 'gamefic/plot/scenes'
12
+ autoload :Commands, 'gamefic/plot/commands'
13
+ autoload :Entities, 'gamefic/plot/entities'
14
+ autoload :Articles, 'gamefic/plot/articles'
15
+ autoload :YouMount, 'gamefic/plot/you_mount'
16
+ autoload :Snapshot, 'gamefic/plot/snapshot'
17
+ autoload :Host, 'gamefic/plot/host'
18
+ autoload :Players, 'gamefic/plot/players'
19
+ autoload :Playbook, 'gamefic/plot/playbook'
20
+ autoload :Callbacks, 'gamefic/plot/callbacks'
21
+ autoload :Theater, 'gamefic/plot/theater'
22
22
 
23
23
  attr_reader :commands, :imported_scripts, :source
24
24
  # TODO: Metadata could use better protection
25
25
  attr_accessor :metadata
26
- include Stage
27
- # @!parse include Gamefic, Tester, Players, SceneMount, CommandMount, Entities
28
- mount Gamefic, Tester, Players, SceneMount, CommandMount, Entities
29
- # @!parse include ArticleMount, YouMount, Snapshot, Host, Callbacks
30
- mount ArticleMount, YouMount, Snapshot, Host, Callbacks
31
- expose :script, :metadata
26
+ include Theater
27
+ include Gamefic, Tester, Players, Scenes, Commands, Entities
28
+ include Articles, YouMount, Snapshot, Host, Callbacks
32
29
 
33
- # @param [Source::Base]
30
+ # @param source [Source::Base]
34
31
  def initialize(source = nil)
35
32
  @source = source || Source::Text.new({})
36
33
  @working_scripts = []
37
34
  @imported_scripts = []
38
35
  @running = false
39
- @playbook = Playbook.new
40
36
  post_initialize
41
37
  end
42
38
 
39
+ # @return [Gamefic::Plot::Playbook]
43
40
  def playbook
44
- @playbook ||= Playbook.new
41
+ @playbook ||= Gamefic::Plot::Playbook.new
45
42
  end
46
43
 
47
44
  def running?
@@ -79,7 +76,9 @@ module Gamefic
79
76
  # Update the Plot's current turn of gameplay.
80
77
  # This method is typically called by the Engine that manages game execution.
81
78
  def update
82
- p_players.each { |p| process_input p }
79
+ entities.each { |e| e.flush }
80
+ call_before_player_update
81
+ p_players.each { |p| p.scene.update }
83
82
  p_entities.each { |e| e.update }
84
83
  call_player_update
85
84
  call_update
@@ -106,24 +105,19 @@ module Gamefic
106
105
  end
107
106
  if !@working_scripts.include?(imported_script) and !imported_scripts.include?(imported_script)
108
107
  @working_scripts.push imported_script
109
- stage imported_script.read, imported_script.absolute_path
108
+ # @hack Arguments need to be in different order if source returns proc
109
+ if imported_script.read.kind_of?(Proc)
110
+ stage &imported_script.read
111
+ else
112
+ stage imported_script.read, imported_script.absolute_path
113
+ end
110
114
  @working_scripts.pop
111
115
  imported_scripts.push imported_script
112
116
  true
113
117
  else
114
118
  false
115
119
  end
116
- end
117
-
118
- private
119
-
120
- def process_input player
121
- line = player.queue.shift
122
- if !line.nil?
123
- player.scene.finish player, line
124
- end
125
- end
126
-
120
+ end
127
121
  end
128
122
 
129
123
  end
@@ -1,22 +1,22 @@
1
- module Gamefic
2
- module Plot::ArticleMount
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
+ 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,6 +1,6 @@
1
1
  module Gamefic
2
2
 
3
- module Plot::Callbacks
3
+ module Plot::Callbacks
4
4
  # Add a block to be executed on preparation of every turn.
5
5
  #
6
6
  # @example Increment a turn counter
@@ -35,6 +35,13 @@ module Gamefic
35
35
  p_player_ready_procs.push block
36
36
  end
37
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
+
38
45
  # Add a block to be executed for each player at the end of a turn.
39
46
  #
40
47
  # @yieldparam [Character]
@@ -58,15 +65,29 @@ module Gamefic
58
65
  p_update_procs.each { |p| p.call }
59
66
  end
60
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
+
61
79
  # Execute the on_player_ready blocks for each player. This method is
62
80
  # typically called by the Plot while beginning a turn, immediately after
63
81
  # the on_ready blocks.
64
82
  #
65
83
  def call_player_ready
66
84
  p_players.each { |player|
67
- this_scene = player.next_scene || player.scene
68
- player.prepare nil
69
- player.cue this_scene unless player.scene == this_scene
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
70
91
  p_player_ready_procs.each { |block| block.call player }
71
92
  }
72
93
  end
@@ -77,6 +98,7 @@ module Gamefic
77
98
  #
78
99
  def call_player_update
79
100
  p_players.each { |player|
101
+ #player.performed nil
80
102
  p_player_update_procs.each { |block| block.call player }
81
103
  }
82
104
  end
@@ -89,6 +111,10 @@ module Gamefic
89
111
  @p_update_procs ||= []
90
112
  end
91
113
 
114
+ def p_before_player_update_procs
115
+ @p_before_player_update_procs ||= []
116
+ end
117
+
92
118
  def p_player_ready_procs
93
119
  @p_player_ready_procs ||= []
94
120
  end
@@ -1,121 +1,121 @@
1
- require 'gamefic/action'
2
-
3
- module Gamefic
4
-
5
- module Plot::CommandMount
6
- # Create an Action that responds to a command.
7
- # An Action uses the command argument to identify the imperative verb that
8
- # triggers the action.
9
- # It can also accept queries to tokenize the remainder of the input and
10
- # filter for particular entities or properties.
11
- # The block argument contains the code to be executed when the input
12
- # matches all of the Action's criteria (i.e., verb and queries).
13
- #
14
- # @example A simple Action.
15
- # respond :salute do |actor|
16
- # actor.tell "Hello, sir!"
17
- # end
18
- # # The command "salute" will respond "Hello, sir!"
19
- #
20
- # @example An Action that accepts a Character
21
- # respond :salute, Use.visible(Character) do |actor, character|
22
- # actor.tell "#{The character} returns your salute."
23
- # end
24
- #
25
- # @param command [Symbol] An imperative verb for the command
26
- # @param *queries [Array<Query::Base>] Queries to filter the command's tokens
27
- # @yieldparam [Character]
28
- def respond(command, *queries, &proc)
29
- playbook.respond(command, *queries, &proc)
30
- end
31
-
32
- # Create a Meta Action that responds to a command.
33
- # Meta Actions are very similar to standard Actions, except the Plot
34
- # understands them to be commands that operate above and/or outside of the
35
- # actual game world. Examples of Meta Actions are commands that report the
36
- # player's current score, save and restore saved games, or list the game's
37
- # credits.
38
- #
39
- # @example A simple Meta Action
40
- # meta :credits do |actor|
41
- # actor.tell "This game was written by John Smith."
42
- # end
43
- #
44
- # @param command [Symbol] An imperative verb for the command
45
- # @param *queries [Array<Query::Base>] Queries to filter the command's tokens
46
- # @yieldparam [Character]
47
- def meta(command, *queries, &proc)
48
- playbook.meta command, *queries, &proc
49
- end
50
-
51
- # @deprecated
52
- def action(command, *queries, &proc)
53
- respond command, *queries, &proc
54
- end
55
-
56
- # Declare a dismabiguation response for actions.
57
- # The disambigurator is executed when an action expects an argument to
58
- # reference a specific entity but its query matched more than one. For
59
- # example, "red" might refer to either a red key or a red book.
60
- #
61
- # If a disambiguator is not defined, the playbook will use its default
62
- # implementation.
63
- #
64
- # @example Tell the player the list of ambiguous entities.
65
- # disambiguate do |actor, entities|
66
- # actor.tell "I don't know which you mean: #{entities.join_or}."
67
- # end
68
- #
69
- # @yieldparam [Gamefic::Character]
70
- # @yieldparam [Array<Gamefic::Entity>]
71
- def disambiguate &block
72
- playbook.disambiguate &block
73
- end
74
-
75
- # Validate an order before a character can execute its command.
76
- #
77
- # @yieldparam [Gamefic::Director::Order]
78
- def validate &block
79
- playbook.validate &block
80
- end
81
-
82
- # Create an alternate Syntax for an Action.
83
- # The command and its translation can be parameterized.
84
- #
85
- # @example Create a synonym for the Inventory Action.
86
- # interpret "catalogue", "inventory"
87
- # # The command "catalogue" will be translated to "inventory"
88
- #
89
- # @example Create a parameterized synonym for the Look Action.
90
- # interpret "scrutinize :entity", "look :entity"
91
- # # The command "scrutinize chair" will be translated to "look chair"
92
- #
93
- # @param command [String] The format of the original command
94
- # @param translation [String] The format of the translated command
95
- # @return [Syntax] the Syntax object
96
- def interpret command, translation
97
- playbook.interpret command, translation
98
- end
99
-
100
- # @deprecated
101
- def xlate command, translation
102
- interpret command, translation
103
- end
104
-
105
- # Get an Array of available verbs.
106
- # If the to_s parameter is true, convert Symbols to Strings.
107
- #
108
- # @return [Array<Symbol|String>]
109
- def verbs to_s: false
110
- to_s ? playbook.verbs.map { |v| v.to_s } : playbook.verbs
111
- end
112
-
113
- # Get an Array of all Actions defined in the Plot.
114
- #
115
- # @return [Array<Action>]
116
- def actions
117
- playbook.actions
118
- end
119
- end
120
-
121
- end
1
+ require 'gamefic/action'
2
+
3
+ module Gamefic
4
+
5
+ module Plot::Commands
6
+ # Create an Action that responds to a command.
7
+ # An Action uses the command argument to identify the imperative verb that
8
+ # triggers the action.
9
+ # It can also accept queries to tokenize the remainder of the input and
10
+ # filter for particular entities or properties.
11
+ # The block argument contains the code to be executed when the input
12
+ # matches all of the Action's criteria (i.e., verb and queries).
13
+ #
14
+ # @example A simple Action.
15
+ # respond :salute do |actor|
16
+ # actor.tell "Hello, sir!"
17
+ # end
18
+ # # The command "salute" will respond "Hello, sir!"
19
+ #
20
+ # @example An Action that accepts a Character
21
+ # respond :salute, Use.visible(Character) do |actor, character|
22
+ # actor.tell "#{The character} returns your salute."
23
+ # end
24
+ #
25
+ # @param command [Symbol] An imperative verb for the command
26
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
27
+ # @yieldparam [Character]
28
+ def respond(command, *queries, &proc)
29
+ playbook.respond(command, *queries, &proc)
30
+ end
31
+
32
+ # Create a Meta Action that responds to a command.
33
+ # Meta Actions are very similar to standard Actions, except the Plot
34
+ # understands them to be commands that operate above and/or outside of the
35
+ # actual game world. Examples of Meta Actions are commands that report the
36
+ # player's current score, save and restore saved games, or list the game's
37
+ # credits.
38
+ #
39
+ # @example A simple Meta Action
40
+ # meta :credits do |actor|
41
+ # actor.tell "This game was written by John Smith."
42
+ # end
43
+ #
44
+ # @param command [Symbol] An imperative verb for the command
45
+ # @param queries [Array<Query::Base>] Filters for the command's tokens
46
+ # @yieldparam [Character]
47
+ def meta(command, *queries, &proc)
48
+ playbook.meta command, *queries, &proc
49
+ end
50
+
51
+ # @deprecated
52
+ def action(command, *queries, &proc)
53
+ respond command, *queries, &proc
54
+ end
55
+
56
+ # Declare a dismabiguation response for actions.
57
+ # The disambigurator is executed when an action expects an argument to
58
+ # reference a specific entity but its query matched more than one. For
59
+ # example, "red" might refer to either a red key or a red book.
60
+ #
61
+ # If a disambiguator is not defined, the playbook will use its default
62
+ # implementation.
63
+ #
64
+ # @example Tell the player the list of ambiguous entities.
65
+ # disambiguate do |actor, entities|
66
+ # actor.tell "I don't know which you mean: #{entities.join_or}."
67
+ # end
68
+ #
69
+ # @yieldparam [Gamefic::Character]
70
+ # @yieldparam [Array<Gamefic::Entity>]
71
+ def disambiguate &block
72
+ playbook.disambiguate &block
73
+ end
74
+
75
+ # Validate an order before a character can execute its command.
76
+ #
77
+ # @yieldparam [Gamefic::Director::Order]
78
+ def validate &block
79
+ playbook.validate &block
80
+ end
81
+
82
+ # Create an alternate Syntax for an Action.
83
+ # The command and its translation can be parameterized.
84
+ #
85
+ # @example Create a synonym for the Inventory Action.
86
+ # interpret "catalogue", "inventory"
87
+ # # The command "catalogue" will be translated to "inventory"
88
+ #
89
+ # @example Create a parameterized synonym for the Look Action.
90
+ # interpret "scrutinize :entity", "look :entity"
91
+ # # The command "scrutinize chair" will be translated to "look chair"
92
+ #
93
+ # @param command [String] The format of the original command
94
+ # @param translation [String] The format of the translated command
95
+ # @return [Syntax] the Syntax object
96
+ def interpret command, translation
97
+ playbook.interpret command, translation
98
+ end
99
+
100
+ # @deprecated
101
+ def xlate command, translation
102
+ interpret command, translation
103
+ end
104
+
105
+ # Get an Array of available verbs.
106
+ # If the to_s parameter is true, convert Symbols to Strings.
107
+ #
108
+ # @return [Array<Symbol|String>]
109
+ def verbs to_s: false
110
+ to_s ? playbook.verbs.map { |v| v.to_s } : playbook.verbs
111
+ end
112
+
113
+ # Get an Array of all Actions defined in the Plot.
114
+ #
115
+ # @return [Array<Action>]
116
+ def actions
117
+ playbook.actions
118
+ end
119
+ end
120
+
121
+ end