Module: Gamefic::Scriptable

Includes:
Actions, Events, Proxy, Queries, Scenes
Included in:
Narrative
Defined in:
lib/gamefic/scriptable.rb,
lib/gamefic/scriptable/proxy.rb,
lib/gamefic/scriptable/events.rb,
lib/gamefic/scriptable/scenes.rb,
lib/gamefic/scriptable/actions.rb,
lib/gamefic/scriptable/queries.rb,
lib/gamefic/scriptable/entities.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, Proxy, Queries, Scenes

Instance Method Summary collapse

Methods included from Scenes

#block, #conclusion, #introduction, #multiple_choice, #pause, #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

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

Methods included from Proxy

#proxy, #unproxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

:nocov:



132
133
134
135
136
# File 'lib/gamefic/scriptable.rb', line 132

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) ⇒ Object

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:



121
122
123
124
125
126
127
128
# File 'lib/gamefic/scriptable.rb', line 121

def attr_seed name, klass, **opts
  @count ||= 0
  seed do
    instance_variable_set("@#{name}", make(klass, **opts))
    self.class.define_method(name) { instance_variable_get("@#{name}") }
  end
  @count.tap { @count += 1 }
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

#make_seed(klass, **opts) ⇒ Object

Seed an entity.

Examples:

make_seed Gamefic::Entity, name: 'thing'

Parameters:



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

def make_seed klass, **opts
  @count ||= 0
  seed { make(klass, **opts) }
  @count.tap { @count += 1 }
end

#no_scriptsModule

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.

Examples:

# Plot and Subplot will both include the `info` method, but
# only Plot will implement the `think` action.

module Shared
  extend Gamefic::Scriptable

  def info
    "This method was added by the Shared module."
  end

  respond :think do |actor|
    actor.tell 'You ponder your predicament.'
  end
end

class Plot < Gamefic::Plot
  include Shared
end

class Subplot < Gamefic::Subplot
  include Shared.no_scripts
end

Returns:

  • (Module)


182
183
184
185
186
# File 'lib/gamefic/scriptable.rb', line 182

def no_scripts
  Module.new.tap do |mod|
    append_features(mod)
  end
end

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

Returns:

  • (Boolean)


146
147
148
149
# File 'lib/gamefic/scriptable.rb', line 146

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