inform-runtime 1.4.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 474087cc0143425969470924c1fe5e944b06f2d17ee76a097551345c4ca1959e
4
- data.tar.gz: 8f933a9f47d17a247d804d226a32f8ff7d57e38698d0b0a262e40a796efd7972
3
+ metadata.gz: a0411c83f9c461e9b8f2687c5f27aa49591933e786f74efa489ca111b3cf9b74
4
+ data.tar.gz: 582fa29d5e602c4e36a499dcc259e21391fa3982348f7fcb2196b8a740c028e3
5
5
  SHA512:
6
- metadata.gz: 606603f0fa1048e8cf566204167646989a99b1fcc80746ec3c8a7490d737ced8cdfb09be0e0cc7b0674123ed96b8588b387f6ed010328963c700816c172167a1
7
- data.tar.gz: 3bab288d8358fcf11ca366756a1e451f3cfab0b231aa7e35d144397b4cba04257b1a92f2406581611628c03521d986db01aa32501818fe059f85f439d2a34370
6
+ metadata.gz: 3ccb26de6ef43e0bedeaf044b964c30ecba16e09809a5c081f32aac1acacfe1644a321cc1f9b68483f1f70496a17e72892fd55a596ba95f83cdc72011f41fa44
7
+ data.tar.gz: ce1fb4b1b4993d8ff7ccd230ee141d1c5347b08c85cc9a074873ff7d66753f588289460dcf9fef0d4aababeb6c98cd09724ebb562f9dfe5381cb108ec2942c88
data/README.md CHANGED
@@ -129,7 +129,6 @@ Sun May 10 09:36:13 CDT 2026
129
129
  │ │ ├── io.rb
130
130
  │ │ ├── kernel.rb
131
131
  │ │ ├── library
132
- │ │ │ ├── bootstrap.rb
133
132
  │ │ │ ├── declarations.rb
134
133
  │ │ │ ├── directives.rb
135
134
  │ │ │ ├── loader.rb
@@ -21,6 +21,8 @@
21
21
 
22
22
  # The StoryTeller module
23
23
  module StoryTeller
24
+ # The English module
25
+ module English
24
26
  # The Articles module
25
27
  # Support standard StoryTeller methods for dynamically applying appropriate
26
28
  # articles to nouns.
@@ -99,13 +101,15 @@ module StoryTeller
99
101
  end
100
102
  # module Articles
101
103
  end
104
+ # module English
105
+ end
102
106
  # module StoryTeller
103
107
 
104
108
  # module Inform
105
109
  module Inform
106
110
  # Re-open the Inform::Parser module
107
111
  module Parser
108
- include StoryTeller::Articles
112
+ include StoryTeller::English::Articles
109
113
 
110
114
  VowelsOrHiPattern = %r{^([aeiou]|hi).+}.freeze
111
115
 
@@ -137,7 +141,7 @@ module Inform
137
141
  # module Parser
138
142
 
139
143
  module Verbs
140
- include StoryTeller::Articles
144
+ include StoryTeller::English::Articles
141
145
  end
142
146
  end
143
147
  # module Inform
@@ -30,7 +30,7 @@ require_relative 'plurals'
30
30
  module StoryTeller
31
31
  # module Builtins
32
32
  module Builtins
33
- include StoryTeller::Articles
33
+ include StoryTeller::English::Articles
34
34
  include StoryTeller::Color
35
35
  include StoryTeller::Plurals
36
36
 
@@ -57,6 +57,7 @@ module Builtins
57
57
  # rubocop: disable Metrics/PerceivedComplexity
58
58
  def with(context = nil, &block)
59
59
  return self if block.nil?
60
+ self.instance_variable_set(:@defining_object, true)
60
61
  existing_methods = self.singleton_methods(false)
61
62
 
62
63
  if context.nil?
@@ -87,12 +88,19 @@ module Builtins
87
88
  end
88
89
  self.save_changes if self.respond_to?(:save_changes)
89
90
  self
91
+ ensure
92
+ self.remove_instance_variable(:@defining_object) if self.instance_variable_defined?(:@defining_object)
90
93
  end
91
94
  # rubocop: enable Metrics/AbcSize
92
95
  # rubocop: enable Metrics/CyclomaticComplexity
93
96
  # rubocop: enable Metrics/MethodLength
94
97
  # rubocop: enable Metrics/PerceivedComplexity
95
98
 
99
+ def defining_object?
100
+ self.instance_variable_defined?(:@defining_object) &&
101
+ self.instance_variable_get(:@defining_object) == true
102
+ end
103
+
96
104
  MethodDefinitionPattern = /\s*def\s+/.freeze
97
105
  MethodTerminationPattern = /\s*end$/.freeze
98
106
 
@@ -107,6 +115,7 @@ module Builtins
107
115
  end
108
116
 
109
117
  def apply_instance_behavior!
118
+ self.properties ||= {}
110
119
  source = self.properties[:instance_behavior]
111
120
  return if source.nil? || source.empty?
112
121
  return unless source.include?('def ')
@@ -138,7 +147,7 @@ module Builtins
138
147
 
139
148
  def react_after?(action_routine = action)
140
149
  return false if action_routine.nil?
141
- self.apply_modules if self.respond_to?(:apply_modules)
150
+ self.apply_modules! if self.respond_to?(:apply_modules!)
142
151
  self.provides?('react_after_' + action_routine)
143
152
  rescue StandardError => e
144
153
  log.error "Error checking for after reaction: #{e.message}", e
@@ -147,7 +156,7 @@ module Builtins
147
156
 
148
157
  def react_before?(action_routine = action)
149
158
  return false if action_routine.nil?
150
- self.apply_modules if self.respond_to?(:apply_modules)
159
+ self.apply_modules! if self.respond_to?(:apply_modules!)
151
160
  self.provides?('react_before_' + action_routine)
152
161
  rescue StandardError => e
153
162
  log.error "Error checking for before reaction: #{e.message}", e
@@ -156,7 +165,7 @@ module Builtins
156
165
 
157
166
  def life?(action_routine = action)
158
167
  return false if action_routine.nil?
159
- self.apply_modules if self.respond_to?(:apply_modules)
168
+ self.apply_modules! if self.respond_to?(:apply_modules!)
160
169
  self.provides?('life_' + action_routine)
161
170
  rescue StandardError => e
162
171
  log.error "Error checking for life reaction: #{e.message}", e
@@ -182,15 +191,27 @@ module Builtins
182
191
  # rubocop: disable Metrics/AbcSize
183
192
  # rubocop: disable Metrics/CyclomaticComplexity
184
193
  # rubocop: disable Metrics/MethodLength
194
+ # rubocop: disable Metrics/PerceivedComplexity
185
195
  def findobject(*args, &block)
186
196
  object_class = inform_object_class
187
197
 
198
+
188
199
  if sequel_model?(object_class)
189
- return object_class.dataset.order(:name, :id).grep(:name, *args).to_a if args.first.is_a?(Regexp)
200
+ if args.first.is_a?(Regexp)
201
+ return object_class.dataset.order(:name, :id).all.select do |object|
202
+ object_name_matches?(object, args.first)
203
+ end
204
+ end
190
205
 
191
206
  return object_class.dataset.grep(&block).to_a
192
207
  end
193
208
 
209
+ # if sequel_model?(object_class)
210
+ # return object_class.dataset.order(:name, :id).grep(:name, *args).to_a if args.first.is_a?(Regexp)
211
+
212
+ # return object_class.dataset.grep(&block).to_a
213
+ # end
214
+
194
215
  objects = inform_object_collection
195
216
  if args.first.is_a?(Regexp)
196
217
  return objects.select do |object|
@@ -203,6 +224,7 @@ module Builtins
203
224
  # rubocop: enable Metrics/AbcSize
204
225
  # rubocop: enable Metrics/CyclomaticComplexity
205
226
  # rubocop: enable Metrics/MethodLength
227
+ # rubocop: enable Metrics/PerceivedComplexity
206
228
 
207
229
  def inform_object_class
208
230
  if defined?(Inform::Object) && sequel_model?(Inform::Object)
@@ -239,7 +261,7 @@ module Builtins
239
261
  Array(name).any? { |part| part.to_s.match?(pattern) } || name.to_s.match?(pattern)
240
262
  end
241
263
 
242
- def deadflag; @deadflag; end
264
+ def deadflag; @deadflag ||= 0; end
243
265
 
244
266
  def deadflag=(flag); @deadflag = flag; end
245
267
 
@@ -267,6 +289,10 @@ module Builtins
267
289
  alias text topic
268
290
 
269
291
  def number(x = nil)
292
+ if !x.nil? && self.object? && self.defining_object?
293
+ self.properties[:number] = x
294
+ return
295
+ end
270
296
  return special_number1 if x.nil?
271
297
  LanguageNumber(x)
272
298
  ''
@@ -343,20 +369,20 @@ module Builtins
343
369
  publish :disconnect
344
370
  end
345
371
 
346
- def __verify(*args)
347
- StoryTeller::Runtime.instance.verify_game(*args)
372
+ def __verify(*args, &block)
373
+ StoryTeller::Runtime.instance.verify_game(*args, &block)
348
374
  end
349
375
 
350
- def __restart(*args)
351
- StoryTeller::Runtime.instance.restart_game(*args)
376
+ def __restart(*args, &block)
377
+ StoryTeller::Runtime.instance.restart_game(*args, &block)
352
378
  end
353
379
 
354
- def __save(*args)
355
- StoryTeller::Runtime.instance.save_game(*args)
380
+ def __save(*args, &block)
381
+ StoryTeller::Runtime.instance.save_game(*args, &block)
356
382
  end
357
383
 
358
- def __restore(*args)
359
- StoryTeller::Runtime.instance.restore_game(*args)
384
+ def __restore(*args, &block)
385
+ StoryTeller::Runtime.instance.restore_game(*args, &block)
360
386
  end
361
387
 
362
388
  # ----------------------------------------------------------------------------
@@ -33,7 +33,9 @@ module StoryTeller
33
33
  module Library
34
34
  def play
35
35
  log.debug "Using engine-managed InformLibrary play method override"
36
- StoryTeller::Engine.library.tap(&:play)
36
+ runtime = StoryTeller::Runtime.instance
37
+ key = runtime&.player_object || Inform::Parser::SelfObj
38
+ StoryTeller::Engine.library(key).tap(&:play)
37
39
  end
38
40
  end
39
41
 
@@ -59,46 +61,14 @@ module StoryTeller
59
61
  @libraries ||= {}
60
62
  end
61
63
 
62
- def player_object
63
- @player_object || parser_selfobj
64
- end
65
-
66
- def player_object=(object)
67
- raise ManagedLibraryError, "player object is nil" if object.nil?
68
-
69
- @player_object = object
70
- replace_parser_selfobj(object)
71
- libraries.clear
72
- end
73
-
74
- def library(selfobj = player_object)
75
- return libraries[selfobj] if !selfobj.nil? && libraries.key?(selfobj)
76
-
77
- inflib = InformLibrary.new.tap { |inflib| inflib.selfobj = selfobj }
78
- bind_managed_library(inflib)
79
- end
80
-
81
- def replace_parser_selfobj(object)
82
- return object unless defined?(Inform::Parser)
83
-
84
- Inform::Parser.send(:remove_const, :SelfObj) if Inform::Parser.const_defined?(:SelfObj, false)
85
- Inform::Parser.const_set(:SelfObj, object)
86
-
87
- object
88
- end
89
-
90
- def bind_managed_library(inform_library)
91
- raise ManagedLibraryError, "InformLibrary is nil" if inform_library.nil?
92
-
93
- selfobj = inform_library.selfobj
94
- raise ManagedLibraryError, "InformLibrary selfobj is nil" if selfobj.nil?
95
-
96
- libraries[selfobj] = inform_library
97
- selfobj.inflib = inform_library if selfobj.respond_to?(:inflib=)
64
+ def library(key)
65
+ return libraries[key] if !key.nil? && libraries.key?(key)
98
66
 
67
+ inform_library = InformLibrary.new
68
+ inform_library.selfobj = key
69
+ key.inflib = inform_library if key.respond_to?(:inflib=)
99
70
  seed_library_location(inform_library) if location_unset?(inform_library)
100
-
101
- inform_library
71
+ libraries[key] = inform_library
102
72
  end
103
73
 
104
74
  def seed_library_location(inflib)
@@ -112,10 +82,14 @@ module StoryTeller
112
82
  inflib&.instance_variable_get(:@location).nil?
113
83
  end
114
84
 
115
- def parser_selfobj
116
- return nil unless defined?(Inform::Parser::SelfObj)
85
+ def listeners
86
+ @listeners ||= []
87
+ end
117
88
 
118
- Inform::Parser::SelfObj
89
+ def included_library(path)
90
+ listeners.each do |listener|
91
+ listener.after_library_included(path)
92
+ end
119
93
  end
120
94
 
121
95
  def main_object=(obj)
@@ -180,6 +154,12 @@ module StoryTeller
180
154
  StoryTeller::IO::Session.players.include?(obj)
181
155
  end
182
156
 
157
+ def ensure_models_ready
158
+ return unless defined? ObjectSetup
159
+
160
+ ObjectSetup.up if ObjectSetup.respond_to?(:up)
161
+ end
162
+
183
163
  def prime_dictionary
184
164
  Inform::Object.select_map(:name).compact.each do |n|
185
165
  Array(n).join(' ').split(/[,\s]+/).grep_v(/[^a-z]/i).map(&:downcase).map(&:to_sym).each do |word|
@@ -304,7 +304,7 @@ module Inform
304
304
  end
305
305
 
306
306
  def all(actor = nil, grammar_index = self)
307
- return grammar_index.map(&:keys).flatten.sort if actor.nil?
307
+ return grammar_index.keys.flatten.sort if actor.nil?
308
308
  mode = role(actor)
309
309
  unless Inform::Grammar.partitions.include?(mode)
310
310
  init_all_verbs_by_mode(mode, grammar_index, actor)
@@ -335,7 +335,7 @@ module Inform
335
335
  verbs = grammar_index.each_with_object(set) do |(key, verb), memo|
336
336
  memo.add(key) unless Profanity.include?(key) || !visible_to?(verb, actor)
337
337
  end
338
- Inform::Grammar.partitions[mode] = verbs.to_a
338
+ Inform::Grammar.partitions[mode] = verbs.to_a.sort
339
339
  end
340
340
 
341
341
  def init_verbs_filtered_by_mode(mode, grammar_index, set = verbs_set_instance)
@@ -94,7 +94,7 @@ module Inform
94
94
  # The Inform::Modular module
95
95
  module Modular
96
96
  def after_initialize
97
- self.apply_modules
97
+ self.apply_modules!
98
98
  super
99
99
  end
100
100
 
@@ -110,7 +110,7 @@ module Inform
110
110
  add_module(Inform::Module.find_or_create(name: mod))
111
111
  end
112
112
  save
113
- apply_modules
113
+ apply_modules!
114
114
  self
115
115
  end
116
116
 
@@ -133,7 +133,7 @@ module Inform
133
133
  modules.compact.map(&:to_s)
134
134
  end
135
135
 
136
- def apply_modules(exceptions = [])
136
+ def apply_modules!(exceptions = [])
137
137
  nil_safe_modules.each do |module_name|
138
138
  next if exceptions.include?(module_name.to_sym)
139
139
  mod = find_module(module_name)
@@ -75,6 +75,7 @@ module Inform
75
75
  EphemeralObjects[self.identity] = self
76
76
  EphemeralObjects[@display_name.to_s] = self unless @display_name.nil?
77
77
  self.with(&block) unless block.nil?
78
+ log.debug "Initializing #{self}" unless textual_name.nil?
78
79
  end
79
80
  # rubocop: enable Metrics/AbcSize
80
81
  # rubocop: enable Metrics/MethodLength
@@ -174,6 +175,10 @@ module Inform
174
175
  @children << o
175
176
  end
176
177
 
178
+ def >(other)
179
+ self << other
180
+ end
181
+
177
182
  def remove
178
183
  @children.clear
179
184
  @parent = nil
@@ -23,6 +23,10 @@
23
23
  module StoryTeller
24
24
  # The IO module
25
25
  module IO
26
+ class << self
27
+ attr_accessor :default_output
28
+ end
29
+
26
30
  def session
27
31
  return @session if defined?(@session) && !@session.nil?
28
32
  return nil unless defined?(StoryTeller::IO::Session)
@@ -43,13 +47,17 @@ module StoryTeller
43
47
  end
44
48
 
45
49
  def out(s)
46
- if defined?(Curses)
47
- Curses.addstr s
48
- elsif session
49
- session.write_output(s)
50
+ current_session = session
51
+ current_session ||= inflib.session if respond_to?(:inflib) && inflib
52
+
53
+ if current_session
54
+ current_session.write_output(s)
55
+ elsif StoryTeller::IO.default_output
56
+ StoryTeller::IO.default_output.write(s)
50
57
  else
51
58
  $stdout.write(s)
52
59
  end
60
+ true
53
61
  end
54
62
 
55
63
  def inform(s = '')
@@ -87,6 +95,14 @@ module StoryTeller
87
95
  out(s.to_s + "\n")
88
96
  end
89
97
 
98
+ def print_routine_result(value)
99
+ return value unless value.is_a?(String)
100
+
101
+ print value
102
+ new_line
103
+ true
104
+ end
105
+
90
106
  def output_stream(i, s); end
91
107
 
92
108
  def reset_prompt
@@ -47,7 +47,7 @@ module Kernel
47
47
  StoryTeller::Library::Directives.Default(property, value)
48
48
  end
49
49
 
50
- def Constant(property, value)
50
+ def Constant(property, value = nil)
51
51
  StoryTeller::Library::Directives.Constant(property, value)
52
52
  end
53
53
 
@@ -55,6 +55,18 @@ module Kernel
55
55
  StoryTeller::Library::Directives.Link(link)
56
56
  end
57
57
 
58
+ def Replace(subroutine_method_name)
59
+ StoryTeller::Library::VerbSubroutineReplacements << subroutine_method_name
60
+ end
61
+
62
+ def Release(release)
63
+ reset_constant :HDR_GAMERELEASE, release
64
+ end
65
+
66
+ def Serial(serial)
67
+ reset_constant :HDR_GAMESERIAL, serial
68
+ end
69
+
58
70
  def import_global(symbol)
59
71
  StoryTeller::Library::Directives.import_global(symbol)
60
72
  end
@@ -65,9 +77,9 @@ module Kernel
65
77
  end
66
78
 
67
79
  raise MethodAlreadyDefined, :reset_constant if respond_to?(:reset_constant)
68
- def reset_constant(constant, value, target = Object)
80
+ def reset_constant(constant, value, target = ::Object)
69
81
  return if constant.nil?
70
- silence_warnings do
82
+ with_warnings_silenced do
71
83
  target.instance_eval { const_set(constant.to_sym, value) }
72
84
  end
73
85
  rescue StandardError => e
@@ -77,7 +89,7 @@ module Kernel
77
89
 
78
90
  raise MethodAlreadyDefined, :toggle_constant if respond_to?(:toggle_constant)
79
91
  def toggle_constant(constant, target = ::Object)
80
- silence_warnings do
92
+ with_warnings_silenced do
81
93
  if target.const_defined?(constant)
82
94
  target.instance_eval { remove_const(constant) }
83
95
  else
@@ -164,7 +176,7 @@ module Kernel
164
176
 
165
177
  raise MethodAlreadyDefined, :reload_feature if respond_to?(:reload_feature)
166
178
  def reload_feature(feature)
167
- silence_warnings do
179
+ with_warnings_silenced do
168
180
  # Remove a loaded feature:
169
181
  load_service.remove_internal_loaded_feature(feature)
170
182
  # Supposedly, purge old compiled script code:
@@ -294,8 +306,8 @@ remove_method :original_rand
294
306
  new_method
295
307
  end
296
308
 
297
- raise MethodAlreadyDefined, :silence_warnings if respond_to?(:silence_warnings)
298
- def silence_warnings(&_block)
309
+ raise MethodAlreadyDefined, :with_warnings_silenced if respond_to?(:with_warnings_silenced)
310
+ def with_warnings_silenced
299
311
  old_verbose = $VERBOSE
300
312
  $VERBOSE = nil
301
313
  yield
@@ -23,6 +23,9 @@
23
23
  module StoryTeller
24
24
  # The StoryTeller::Library module
25
25
  module Library
26
+ class Memo < Array; end
27
+ VerbSubroutineReplacements = Memo.new
28
+
26
29
  # The StoryTeller::Library::Directives module
27
30
  module Directives
28
31
  InclusionGrammarGuessTemplate = '%<inclusion>s.h.inf.rb'.freeze
@@ -38,10 +41,12 @@ module StoryTeller
38
41
  # were ephemeral in nature.
39
42
  end
40
43
 
44
+ # rubocop: disable Metrics/AbcSize
45
+ # rubocop: disable Metrics/MethodLength
41
46
  def Include(inclusion)
42
- # warn "StoryTeller::Engine.Include(#{inclusion}) from #{caller_locations(1, 5).map { |l|
43
- # "#{l.path}:#{l.lineno}"
44
- # }.join(' | ')}"
47
+ log.debug "StoryTeller::Engine.Include(#{inclusion}) from #{caller_locations(1, 5).map do |l|
48
+ "#{l.path}:#{l.lineno}"
49
+ end.join(' | ')}"
45
50
  inclusion = StoryTeller::Engine.language_name if /^language__$/.match(inclusion)
46
51
  grammar_guess = format(InclusionGrammarGuessTemplate, inclusion: inclusion)
47
52
  guess = File.expand_path(
@@ -50,9 +55,13 @@ module StoryTeller
50
55
  StoryTeller::Engine.inform_code_prefix,
51
56
  grammar_guess))
52
57
  return StoryTeller::Library::Loader.load_grammar_by_path(guess) if File.exist?(guess)
53
- StoryTeller::Library::Loader.require_first_existing(
58
+ loaded_path = StoryTeller::Library::Loader.require_first_existing(
54
59
  format(InclusionGuessesTemplate, inclusion: inclusion).split)
60
+ StoryTeller::Engine.included_library(loaded_path)
61
+ loaded_path
55
62
  end
63
+ # rubocop: enable Metrics/AbcSize
64
+ # rubocop: enable Metrics/MethodLength
56
65
 
57
66
  def Attribute(attribute)
58
67
  StoryTeller::Library.declarations.add_attribute(attribute)
@@ -66,19 +75,64 @@ module StoryTeller
66
75
  end
67
76
  end
68
77
 
69
- def Default(property, value)
70
- Constant(property, value)
78
+ # rubocop: disable Metrics/MethodLength
79
+ def Default(property, value, target = ::Object)
80
+ inform_name = property.to_sym
81
+ ruby_name = if property.to_s.match?(/\A[A-Z][A-Za-z0-9_]*\z/)
82
+ inform_name
83
+ else
84
+ property.to_s.upcase.to_sym
85
+ end
86
+
87
+ value = begin
88
+ target.const_get(ruby_name)
89
+ rescue RuntimeError => _e
90
+ # Ignore error
91
+ rescue StandardError => _e
92
+ # Ignore error
93
+ end
94
+
95
+ reset_constant(ruby_name, value, target) if value.nil?
96
+
97
+ return value if inform_name == ruby_name
98
+
99
+ install_global_reader(inform_name, ruby_name, target)
100
+ rescue StandardError => e
101
+ log.error "Unexpected error resetting default #{property}", e
102
+ nil
71
103
  end
104
+ # rubocop: enable Metrics/MethodLength
72
105
 
73
- def Constant(constant, value, target = ::Object)
74
- return if constant.nil?
75
- silence_warnings do
76
- target.instance_eval { const_set(constant.to_sym, value) }
106
+ # rubocop: disable Metrics/MethodLength
107
+ def Constant(constant, value = nil, target = ::Object)
108
+ inform_name = constant.to_sym
109
+ ruby_name = if constant.to_s.match?(/\A[A-Z][A-Za-z0-9_]*\z/)
110
+ inform_name
111
+ else
112
+ constant.to_s.upcase.to_sym
77
113
  end
114
+
115
+ log.debug "Setting constant #{target}.#{ruby_name} to #{value}"
116
+ log.debug " inform_name: #{inform_name}"
117
+ reset_constant(ruby_name, value, target)
118
+
119
+ return value if inform_name == ruby_name
120
+
121
+ install_global_reader(inform_name, ruby_name, target)
78
122
  rescue StandardError => e
79
123
  log.error "Unexpected error resetting constant #{constant}", e
80
124
  nil
81
125
  end
126
+ # rubocop: enable Metrics/MethodLength
127
+
128
+ def install_global_reader(inform_name, ruby_name, target = ::Object)
129
+ reader = -> { target.target.instance_eval { const_get(ruby_name) } }
130
+
131
+ Kernel.define_method(inform_name, &reader)
132
+ Kernel.send(:private, inform_name)
133
+
134
+ InformLibrary.define_method(inform_name, &reader) if defined?(InformLibrary)
135
+ end
82
136
 
83
137
  def import_global(symbol)
84
138
  StoryTeller::Library.declarations.add_global(symbol)
@@ -55,9 +55,11 @@ module StoryTeller
55
55
  if File.exist?(guessed_local_file_path)
56
56
  log.debug "Loading local library file: #{guessed_local_file_path}"
57
57
  require_relative guessed_local_file_path
58
+ return guessed_local_file_path
58
59
  else
59
60
  log.debug "Loading library: #{guessed_file_path}"
60
61
  require guessed_file_path
62
+ return guessed_file_path
61
63
  end
62
64
  rescue StandardError => e
63
65
  log.error e.message
@@ -26,7 +26,7 @@ module StoryTeller
26
26
  # module Location
27
27
  module Location
28
28
  def location
29
- @player&.location || @location
29
+ @location
30
30
  end
31
31
 
32
32
  def location=(obj)
@@ -19,7 +19,6 @@
19
19
  # You should have received a copy of the GNU General Public License
20
20
  # along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
21
21
 
22
- require_relative 'library/bootstrap'
23
22
  require_relative 'library/declarations'
24
23
  require_relative 'library/directives'
25
24
  require_relative 'library/loader'