Module: Gamefic::Scriptable

Includes:
Actions, Events, Queries, Scenes
Included in:
Narrative
Defined in:
lib/gamefic/scriptable.rb,
lib/gamefic/scriptable/events.rb,
lib/gamefic/scriptable/scenes.rb,
lib/gamefic/scriptable/actions.rb,
lib/gamefic/scriptable/proxies.rb,
lib/gamefic/scriptable/queries.rb,
lib/gamefic/scriptable/entities.rb,
lib/gamefic/scriptable/plot_proxies.rb

Overview

A class module that enables scripting.

Narratives extend Scriptable to enable definition of scripts and seeds. Modules can also be extended with Scriptable to make them includable to other Scriptables.

Examples:

Include a scriptable module in a plot

module MyScript
  extend Gamefic::Scriptable

  respond :myscript do |actor|
    actor.tell "This command was added by MyScript"
  end
end

class MyPlot < Gamefic::Plot
  include MyScript
end

Defined Under Namespace

Modules: Actions, Entities, Events, PlotProxies, Proxies, Queries, Scenes

Instance Method Summary collapse

Methods included from Scenes

#block, #conclusion, #introduction, #multiple_choice, #pause, #preface, #scene, #scenes, #yes_or_no

Methods included from Events

#on_conclude, #on_player_conclude, #on_player_output, #on_player_ready, #on_player_update, #on_ready, #on_update

Methods included from Actions

#after_action, #before_action, #interpret, #meta, #respond, #synonyms, #syntaxes, #verbs

Methods included from Queries

#abstract, #anywhere, #available, #children, #descendants, #myself, #parent, #plaintext, #siblings

Methods included from Proxies

#unproxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, **kwargs, &block) ⇒ Object

:nocov:



195
196
197
198
199
# File 'lib/gamefic/scriptable.rb', line 195

def method_missing method, *args, &block
  return super unless respond_to_missing?(method)

  script { send(method, *args, &block) }
end

Instance Method Details

#attr_seed(name, klass, **opts) ⇒ Proxy

Seed an entity with an attribute method.

Examples:

class Plot < Gamefic::Plot
  attr_seed :thing, Gamefic::Entity, name: 'thing'
end

plot = Plot.new
plot.thing #=> #<Gamefic::Entity a thing>

Parameters:

Returns:



124
125
126
127
128
129
130
131
132
133
# File 'lib/gamefic/scriptable.rb', line 124

def attr_seed name, klass, **opts
  ivname = "@#{name}"
  define_method(name) do
    return instance_variable_get(ivname) if instance_variable_defined?(ivname)

    instance_variable_set(ivname, make(klass, **opts))
  end
  seed { send name }
  Proxy.new(:attr, name)
end

#blocksArray<Block> Also known as: scripts

Returns:



41
42
43
# File 'lib/gamefic/scriptable.rb', line 41

def blocks
  @blocks ||= []
end

#included_blocksArray<Block>

Returns:



90
91
92
93
94
95
96
# File 'lib/gamefic/scriptable.rb', line 90

def included_blocks
  included_modules.that_are(Scriptable)
                  .uniq
                  .reverse
                  .flat_map(&:blocks)
                  .concat(blocks)
end

#lazy_attr(key) ⇒ Proxy Also known as: _attr

Lazy reference an entity by its attribute or method.

Examples:

lazy_attr(:method)

Parameters:

  • key (Symbol)

Returns:



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

def lazy_attr key
  Gamefic.logger.warn "#{caller.first ? "#{caller.first}: " : ''}`lazy_attr` is deprecated. Use `pick` or `pick!` instead."
  Proxy.new(:attr, key)
end

#lazy_ivar(key) ⇒ Proxy Also known as: _ivar

Lazy reference an entity by its instance variable.

Examples:

lazy_ivar(:@variable)

Parameters:

  • key (Symbol)

Returns:



153
154
155
156
# File 'lib/gamefic/scriptable.rb', line 153

def lazy_ivar key
  Gamefic.logger.warn "#{caller.first ? "#{caller.first}: " : ''}`lazy_ivar` is deprecated. Use `pick` or `pick!` instead."
  Proxy.new(:ivar, key)
end

#make_seed(klass, **opts) ⇒ Proxy Also known as: make

Seed an entity.

Examples:

make_seed Gamefic::Entity, name: 'thing'

Parameters:

Returns:



105
106
107
108
# File 'lib/gamefic/scriptable.rb', line 105

def make_seed klass, **opts
  seed { make(klass, **opts) }
  Proxy::Pick.new(klass, opts[:name], raise: true)
end

#no_scriptsModule<self>

Deprecated.

Removing script blocks is no longer necessary. This method will simply return self until it’s removed.

Create an anonymous module that includes the features of a Scriptable module but does not include its scripts.

This can be useful when you need access to the Scriptable’s constants and instance methods, but you don’t want to duplicate its rules.

Returns:

  • (Module<self>)


224
225
226
227
# File 'lib/gamefic/scriptable.rb', line 224

def no_scripts
  Logging.logger.warn "#{caller.first ? "#{caller.first}: " : ''}Calling `no_scripts` on Scriptable modules is no longer necessary."
  self
end

#pick(*args) ⇒ Proxy Also known as: lazy_pick, _pick, lazy_pick!, _pick!

Lazy pick an entity.

Examples:

pick('the red box')

Parameters:

Returns:



179
180
181
# File 'lib/gamefic/scriptable.rb', line 179

def pick *args
  Proxy::Pick.new(*args)
end

#pick!(*args) ⇒ Object

Lazy pick an entity or raise



187
188
189
# File 'lib/gamefic/scriptable.rb', line 187

def pick! *args
  Proxy::Pick.new(*args)
end

#proxy(symbol) ⇒ Proxy

Parameters:

  • symbol (Symbol)

Returns:



137
138
139
140
141
142
143
144
# File 'lib/gamefic/scriptable.rb', line 137

def proxy symbol
  Logging.logger.warn "#{caller.first ? "#{caller.first}: " : ''}`proxy` is deprecated. Use `pick` or `pick!` instead."
  if symbol.to_s.start_with?('@')
    Proxy.new(:ivar, symbol)
  else
    Proxy.new(:attr, symbol)
  end
end

#respond_to_missing?(method, _with_private = false) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
212
# File 'lib/gamefic/scriptable.rb', line 209

def respond_to_missing?(method, _with_private = false)
  [Scriptable::Actions, Scriptable::Events, Scriptable::Scenes].flat_map(&:public_instance_methods)
                                                               .include?(method)
end

#script(&block) ⇒ Object

Add a block of code to be executed during initialization.

These blocks are primarily used to define actions, scenes, and hooks in the narrative’s rulebook. Entities and game data should be initialized with ‘seed`.

Examples:

class MyPlot < Gamefic::Plot
  script do
    introduction do |actor|
      actor.tell 'Hello, world!'
    end

    respond :wait do |actor|
      actor.tell 'Time passes.'
    end
  end
end


65
66
67
# File 'lib/gamefic/scriptable.rb', line 65

def script &block
  blocks.push Block.new(:script, block)
end

#seed(&block) ⇒ Object

Note:

Seeds do not get executed when a narrative is restored from a snapshot.

Add a block of code to generate content after initialization.

Seeds run after the initial scripts have been executed. Their primary use is to add entities and other data components, especially randomized or procedurally generated content that can vary between instances.

Examples:

class MyPlot < Gamefic::Plot
  seed do
    @thing = make Gamefic::Entity, name: 'a thing'
  end
end


85
86
87
# File 'lib/gamefic/scriptable.rb', line 85

def seed &block
  blocks.push Block.new(:seed, block)
end