Module: Gamefic::Active

Includes:
Messaging, Logging
Included in:
Actor
Defined in:
lib/gamefic/active.rb,
lib/gamefic/active/cue.rb,
lib/gamefic/active/epic.rb,
lib/gamefic/active/take.rb,
lib/gamefic/active/messaging.rb

Overview

The Active module gives entities the ability to perform actions and participate in scenes. The Actor class, for example, is an Entity subclass that includes this module.

Defined Under Namespace

Modules: Messaging Classes: Cue, Epic, Take

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Messaging

#buffer, #flush, #messages, #messenger, #stream, #tell

Methods included from Logging

logger

Instance Attribute Details

#next_cueActive::Cue? (readonly)

The cue that will be used to create a scene at the beginning of the next turn.

Returns:



22
23
24
# File 'lib/gamefic/active.rb', line 22

def next_cue
  @next_cue
end

Instance Method Details

#accessible?Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/gamefic/active.rb', line 192

def accessible?
  false
end

#conclude(scene, **context) ⇒ Object

Cue a conclusion. This method works like #cue, except it will raise an error if the scene is not a conclusion.

Parameters:

  • new_scene (Symbol)

Raises:

  • (ArgumentError)

    if the requested scene is not a conclusion



178
179
180
181
182
183
184
# File 'lib/gamefic/active.rb', line 178

def conclude scene, **context
  cue scene, **context
  available = epic.select_scene(scene)
  raise ArgumentError, "`#{scene}` is not a conclusion" unless available.conclusion?

  @next_cue
end

#concluding?Boolean

True if the actor is ready to leave the game.

Returns:

  • (Boolean)


188
189
190
# File 'lib/gamefic/active.rb', line 188

def concluding?
  epic.empty? || (@last_cue && epic.conclusion?(@last_cue.scene))
end

#cue(scene, **context) ⇒ Cue Also known as: prepare

Cue a scene to start in the next turn.

Parameters:

  • scene (Symbol)
  • context (Hash)

    Extra data to pass to the scene’s props

Returns:

Raises:

  • (ArgumentError)

    if the scene is not valid



140
141
142
143
144
145
146
# File 'lib/gamefic/active.rb', line 140

def cue scene, **context
  return @next_cue if @next_cue&.scene == scene && @next_cue&.context == context

  logger.debug "Overwriting existing cue `#{@next_cue.scene}` with `#{scene}`" if @next_cue

  @next_cue = Cue.new(scene, **context)
end

#epicEpic

The narratives in which the entity is participating.

Returns:



40
41
42
# File 'lib/gamefic/active.rb', line 40

def epic
  @epic ||= Epic.new
end

#execute(verb, *params) ⇒ Gamefic::Action

Perform an action. This is functionally identical to the ‘perform` method, except the action must be declared as a verb with a list of arguments. Use `perform` if you need to parse a string as a command.

The command will be executed immediately, regardless of the entity’s state.

Examples:

character.execute :take, @key

Parameters:

  • verb (Symbol)
  • params (Array)

Returns:



99
100
101
102
103
# File 'lib/gamefic/active.rb', line 99

def execute(verb, *params)
  dispatchers.push Dispatcher.dispatch_from_params(self, verb, params)
  dispatchers.last.execute
  dispatchers.pop
end

#finish_takeObject



156
157
158
159
160
# File 'lib/gamefic/active.rb', line 156

def finish_take
  return unless @last_cue

  Take.finish(self, @last_cue, @props)
end

#next_sceneSymbol?

Returns:

  • (Symbol, nil)


25
26
27
# File 'lib/gamefic/active.rb', line 25

def next_scene
  next_cue&.scene
end

#outputHash

A hash of data that will be sent to the user. The output is typically sent after a scene has started and before the user is prompted for input.

Returns:

  • (Hash)


55
56
57
# File 'lib/gamefic/active.rb', line 55

def output
  @output ||= {}
end

#perform(command) ⇒ void

This method returns an undefined value.

Perform a command.

The command’s action will be executed immediately, regardless of the entity’s state.

Examples:

Send a command as a string

character.perform "take the key"

Parameters:



69
70
71
72
73
# File 'lib/gamefic/active.rb', line 69

def perform(command)
  dispatchers.push Dispatcher.dispatch(self, command)
  dispatchers.last.execute
  dispatchers.pop
end

#proceedvoid

This method returns an undefined value.

Proceed to the next Action in the current stack. This method is typically used in Action blocks to cascade through multiple implementations of the same verb.

Examples:

Proceed through two implementations of a verb

introduction do |actor|
  actor[:has_eaten] = false # Initial value
end

respond :eat do |actor|
  actor.tell "You eat something."
  actor[:has_eaten] = true
end

respond :eat do |actor|
  # This version will be executed first because it was implemented last
  if actor[:has_eaten]
    actor.tell "You already ate."
  else
    actor.proceed # Execute the previous implementation
  end
end


129
130
131
# File 'lib/gamefic/active.rb', line 129

def proceed
  dispatchers.last&.proceed&.execute
end

#queueArray<String>

An array of commands waiting to be executed.

Returns:



47
48
49
# File 'lib/gamefic/active.rb', line 47

def queue
  @queue ||= []
end

#quietly(command) ⇒ String

Quietly perform a command. This method executes the command exactly as #perform does, except it buffers the resulting output instead of sending it to messages.

Parameters:

Returns:

  • (String)

    The output that resulted from performing the command.



81
82
83
# File 'lib/gamefic/active.rb', line 81

def quietly(command)
  messenger.buffer { perform command }
end

#recueCue?

Restart the scene from the most recent cue.

Returns:



165
166
167
168
169
# File 'lib/gamefic/active.rb', line 165

def recue
  logger.warn "No scene to recue" unless @last_cue

  @next_cue = @last_cue
end

#start_takeObject



149
150
151
152
153
154
# File 'lib/gamefic/active.rb', line 149

def start_take
  ensure_cue
  @last_cue = @next_cue
  cue :default_scene
  @props = Take.start(self, @last_cue)
end