inform-runtime 1.2.2 → 1.3.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -41
  3. data/lib/story_teller/articles.rb +2 -1
  4. data/lib/story_teller/builtins.rb +63 -10
  5. data/lib/story_teller/color.rb +2 -1
  6. data/lib/story_teller/command.rb +4 -1
  7. data/lib/story_teller/context.rb +23 -27
  8. data/lib/story_teller/daemon.rb +2 -2
  9. data/lib/story_teller/engine.rb +80 -16
  10. data/lib/story_teller/events.rb +9 -2
  11. data/lib/story_teller/experimental/handler_dsl.rb +1 -16
  12. data/lib/story_teller/experimental/reverse_engineer_class.rb +1 -1
  13. data/lib/story_teller/grammar_parser.rb +60 -13
  14. data/lib/story_teller/helpers.rb +8 -18
  15. data/lib/story_teller/history.rb +2 -1
  16. data/lib/story_teller/inflector.rb +4 -2
  17. data/lib/story_teller/inform/ephemeral/link.rb +63 -31
  18. data/lib/story_teller/inform/ephemeral/module.rb +6 -5
  19. data/lib/story_teller/inform/ephemeral/object.rb +223 -236
  20. data/lib/story_teller/inform/ephemeral/tag.rb +27 -14
  21. data/lib/story_teller/io.rb +99 -49
  22. data/lib/story_teller/kernel.rb +13 -5
  23. data/lib/story_teller/library/bootstrap.rb +10 -27
  24. data/lib/story_teller/library/declarations.rb +1 -1
  25. data/lib/story_teller/library/directives.rb +1 -1
  26. data/lib/story_teller/library/loader.rb +4 -20
  27. data/lib/story_teller/library/location.rb +9 -3
  28. data/lib/story_teller/library.rb +1 -1
  29. data/lib/story_teller/logging.rb +165 -67
  30. data/lib/story_teller/mixins.rb +11 -4
  31. data/lib/story_teller/plurals.rb +2 -1
  32. data/lib/story_teller/privileges.rb +117 -0
  33. data/lib/story_teller/prototype.rb +158 -32
  34. data/lib/story_teller/publication.rb +2 -1
  35. data/lib/story_teller/session.rb +115 -25
  36. data/lib/story_teller/stdlib.rb +232 -2
  37. data/lib/story_teller/subscription.rb +2 -1
  38. data/lib/story_teller/tree.rb +2 -1
  39. data/lib/story_teller/version.rb +2 -2
  40. data/lib/story_teller/world_tree.rb +21 -23
  41. data/lib/story_teller.rb +18 -5
  42. metadata +7 -10
  43. data/lib/story_teller/core.rb +0 -38
  44. data/lib/story_teller/ephemeral_adapter.rb +0 -40
  45. data/lib/story_teller/inform/base.rb +0 -160
  46. data/lib/story_teller/model_adapter.rb +0 -132
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: false
4
4
 
5
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
5
+ # Copyright Nels Nelson 2008-2026 but freely usable (see license)
6
6
  #
7
7
  # This file is part of StoryTeller.
8
8
  #
@@ -21,6 +21,16 @@
21
21
 
22
22
  require_relative 'version'
23
23
 
24
+ # The Inform module
25
+ module Inform
26
+ # Support WriteListFrom implementations that prefer to skip animate objects
27
+ NONANIMATE_BIT = 0x8000 unless defined?(NONANIMATE_BIT) # 32_768
28
+ # Support WriteListFrom implementations that color animate objects
29
+ COLORANIMATE_BIT = 0x1_0000 unless defined?(COLORANIMATE_BIT) # 65_536
30
+ # Support WriteListFrom implementations that prefer to skip door objects
31
+ NONDOOR_BIT = 0x2_0000 unless defined?(NONDOOR_BIT) # 131_072
32
+ end
33
+
24
34
  # The Inform module
25
35
  module Inform
26
36
  # These are built-ins primarily found used in the InformLibrary.
@@ -432,7 +442,7 @@ module StdLib
432
442
  # appropriate.
433
443
  nil # false
434
444
  rescue StandardError => e
435
- log.error "Error getting reaction from #{obj}", e
445
+ log.error "Error getting reaction from #{obj.identity}", e
436
446
  e.backtrace.each { |t| log.error t }
437
447
  ensure
438
448
  obj.inflib = si
@@ -606,3 +616,223 @@ end
606
616
  # module StdLib
607
617
  end
608
618
  # module Inform
619
+
620
+ # The Inform module
621
+ module Inform
622
+ # The Rules module defines functional additions to the Session state
623
+ # machine. The additional functionality supports user interface patterns
624
+ # commonly found in interactive fiction games, specifically those created
625
+ # using Inform. Supporting the principle of least surprise mandates that
626
+ # the expectations held by the users of such games should be satisfied.
627
+ # TODO: Perhaps this should go in the mudlib
628
+ module Rules
629
+ def ask(s = nil)
630
+ println s if s.is_a?(String)
631
+ if session
632
+ @previous ||= session.state
633
+ session.state = :asked
634
+ end
635
+ # true
636
+ session.state
637
+ end
638
+
639
+ def yesorno(s = nil)
640
+ print s.to_s unless s.nil? # rubocop: disable Lint/RedundantStringCoercion
641
+ unless session.nil?
642
+ @previous ||= session.state
643
+ session.state = :asked
644
+ end
645
+ session&.state || false
646
+ end
647
+
648
+ def asked
649
+ yesorno?
650
+ end
651
+
652
+ # rubocop: disable Metrics/MethodLength
653
+ def yesorno?
654
+ reset_io # TODO: Remove this. Why is the buffer getting a newline character added to it?
655
+ case @buffer.split.first
656
+ when /^(y|yes)$/i
657
+ println(resume)
658
+ responded
659
+ when /^(n|no)$/i
660
+ prompt
661
+ responded
662
+ else
663
+ L__M(:Quit, 1); print "> "
664
+ session&.state
665
+ end
666
+ end
667
+ # rubocop: enable Metrics/MethodLength
668
+
669
+ def disambiguate
670
+ session.state = :disambiguating unless session.nil?
671
+ false
672
+ end
673
+
674
+ def disambiguating
675
+ WhichOne() if @ambiguity
676
+ session.state = :playing unless session.nil?
677
+ end
678
+
679
+ def complete
680
+ session.state = :completing unless session.nil?
681
+ false
682
+ end
683
+
684
+ def completing
685
+ Incomplete() if @ambiguity
686
+ session.state = :playing unless session.nil?
687
+ end
688
+
689
+ SolicitedStates = %i[asked yesorno? solicited].freeze
690
+ def solicit(s = nil)
691
+ if !session.nil? && !SolicitedStates.include?(session.state)
692
+ prompt s if s.is_a?(String)
693
+ @previous ||= session.state
694
+ end
695
+ session.state = :solicited unless session.nil?
696
+ end
697
+
698
+ def disambiguated
699
+ session.state = :playing unless session.nil?
700
+ queue @input
701
+ end
702
+
703
+ def completed
704
+ session.state = :playing unless session.nil?
705
+ queue @input
706
+ end
707
+
708
+ def solicited
709
+ responded? @input
710
+ end
711
+
712
+ def responded
713
+ session&.state = previous_state = @previous
714
+ @previous = nil
715
+ session&.state || previous_state
716
+ end
717
+
718
+ def asked?
719
+ session&.state == :asked
720
+ end
721
+
722
+ def disambiguating?
723
+ session&.state == :disambiguating
724
+ end
725
+
726
+ def completing?
727
+ session&.state == :completing
728
+ end
729
+
730
+ def solicited?
731
+ session&.state == :solicited
732
+ end
733
+
734
+ # rubocop: disable Metrics/MethodLength
735
+ def responded?(_s)
736
+ reset_io # TODO: Remove this. Why is the buffer getting a newline character added to it?
737
+ if @buffer.empty?
738
+ prompt
739
+ else
740
+ responded
741
+ @consult_words = @input = @buffer.dup
742
+ result = resume
743
+ println(result)
744
+ if result == :playing
745
+ reset_prompt
746
+ prompt
747
+ end
748
+ end
749
+ session&.state
750
+ end
751
+ # rubocop: enable Metrics/MethodLength
752
+ end
753
+ # module Rules
754
+ end
755
+ # module Inform
756
+
757
+ # module Inform
758
+ module Inform
759
+ # module Rules
760
+ module Rules
761
+ More = Struct.new(:text, :page_index)
762
+
763
+ DefaultMoreParameters = {
764
+ page_index: 0, limit: 10, help: nil, done: :playing
765
+ }.freeze
766
+
767
+ # This method supports the MoreSub verb implementation.
768
+ # rubocop: disable Metrics/AbcSize
769
+ # rubocop: disable Metrics/CyclomaticComplexity
770
+ # rubocop: disable Metrics/MethodLength
771
+ # rubocop: disable Metrics/PerceivedComplexity
772
+ def more(text = nil, params = {})
773
+ params = DefaultMoreParameters.merge(params)
774
+ text = more_lines(text) unless text.nil?
775
+
776
+ if session.nil?
777
+ println text
778
+ return params[:done]
779
+ end
780
+ input = @buffer.dup
781
+ @more ||= More.new([], params[:page_index])
782
+
783
+ if text
784
+ @more.text = text
785
+ else
786
+ text = @more.text
787
+ end
788
+
789
+ case input
790
+ when /\?/
791
+ println params[:help] || "<Help for More goes here>"
792
+ when /^(q|quit)$/
793
+ @more = nil
794
+ @prompt = nil
795
+ return session.state = params[:done]
796
+ else
797
+ text = @more.text.lines(chomp: true) if @more.text.is_a? String
798
+ unless text.is_a?(Array)
799
+ println "[Error: Format problem using the more command -- cannot handle given text.]"
800
+ return session.state = params[:done]
801
+ end
802
+
803
+ println text[@more.page_index, params[:limit]].join("\n")
804
+
805
+ @more.page_index += params[:limit]
806
+ end
807
+
808
+ percent_complete = [100, (100 * (@more.page_index.to_f / text.length)).floor].min
809
+ @more = nil unless @more.page_index < @more.text.length
810
+
811
+ new_line
812
+ print "--More--(#{percent_complete}%)"
813
+
814
+ if percent_complete < 100
815
+ prompt " [?]: "
816
+ session.state = :more
817
+ else
818
+ new_line
819
+ prompt nil
820
+ session.state = params[:done]
821
+ end
822
+ end
823
+ # def more
824
+ # rubocop: enable Metrics/AbcSize
825
+ # rubocop: enable Metrics/CyclomaticComplexity
826
+ # rubocop: enable Metrics/MethodLength
827
+ # rubocop: enable Metrics/PerceivedComplexity
828
+
829
+ def more_lines(text)
830
+ return text if text.is_a?(Array)
831
+ return text.lines(chomp: true) if text.is_a?(String)
832
+
833
+ nil
834
+ end
835
+ end
836
+ # module Rules
837
+ end
838
+ # module Inform
@@ -1,7 +1,8 @@
1
+ # lib/story_teller/subscription.rb
1
2
  # encoding: utf-8
2
3
  # frozen_string_literal: false
3
4
 
4
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
5
+ # Copyright Nels Nelson 2008-2026 but freely usable (see license)
5
6
  #
6
7
  # This file is part of the StoryTeller.
7
8
  #
@@ -1,7 +1,8 @@
1
+ # lib/story_teller/tree.rb
1
2
  # encoding: utf-8
2
3
  # frozen_string_literal: false
3
4
 
4
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
5
+ # Copyright Nels Nelson 2008-2026 but freely usable (see license)
5
6
  #
6
7
  # This file is part of the StoryTeller.
7
8
  #
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: false
4
4
 
5
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
5
+ # Copyright Nels Nelson 2008-2026 but freely usable (see license)
6
6
  #
7
7
  # This file is part of the StoryTeller.
8
8
  #
@@ -23,7 +23,7 @@
23
23
  module StoryTeller
24
24
  # module Engine
25
25
  module Engine
26
- VERSION = '1.2.2'.freeze
26
+ VERSION = '1.3.1'.freeze
27
27
  end
28
28
  end
29
29
 
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
  # frozen_string_literal: false
4
4
 
5
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
5
+ # Copyright Nels Nelson 2008-2026 but freely usable (see license)
6
6
  #
7
7
  # This file is part of the StoryTeller.
8
8
  #
@@ -19,24 +19,30 @@
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 'inform/models'
22
23
  require_relative 'tree'
23
24
  require_relative 'daemon'
24
25
 
25
- # class Object
26
+ # module Inform
26
27
  module Inform
27
- # class Object
28
- class Object
29
- include StoryTeller::Builtins
30
- include StoryTeller::IO if defined?(StoryTeller::IO)
31
- include StoryTeller::Publisher if defined?(StoryTeller::Publisher)
32
- include StoryTeller::Daemons if defined?(StoryTeller::Daemons)
33
- include Inform::Context if defined?(Inform::Context)
34
- include Inform::Events if defined?(Inform::Events)
35
- include Inform::Prototypical if defined?(Inform::Prototypical)
36
- include Inform::Linkable if defined?(Inform::Linkable)
37
- include Inform::Taggable if defined?(Inform::Taggable)
38
- include Inform::Modular if defined?(Inform::Modular)
39
- include Inform::Genealogical if defined?(Inform::Genealogical)
28
+ include StoryTeller::Builtins unless include?(StoryTeller::Builtins)
29
+
30
+ # module Ephemeral
31
+ module Ephemeral
32
+ # class Object
33
+ class Object
34
+ include StoryTeller::Builtins
35
+ include StoryTeller::IO if defined?(StoryTeller::IO)
36
+ include StoryTeller::Publisher if defined?(StoryTeller::Publisher)
37
+ include StoryTeller::Daemons if defined?(StoryTeller::Daemons)
38
+ include Inform::Context if defined?(Inform::Context)
39
+ include Inform::Events if defined?(Inform::Events)
40
+ include Inform::Prototypical if defined?(Inform::Prototypical)
41
+ prepend Inform::Linkable if defined?(Inform::Linkable)
42
+ include Inform::Taggable if defined?(Inform::Taggable)
43
+ include Inform::Modular if defined?(Inform::Modular)
44
+ include Inform::Genealogical if defined?(Inform::Genealogical)
45
+ end
40
46
  end
41
47
 
42
48
  # class Event
@@ -44,11 +50,3 @@ module Inform
44
50
  include StoryTeller::Publisher
45
51
  end
46
52
  end
47
-
48
- # The ExtendedProperties class
49
- class ExtendedProperties < Inform::Object
50
- def init
51
- has :proper
52
- super
53
- end
54
- end
data/lib/story_teller.rb CHANGED
@@ -19,8 +19,21 @@
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 'story_teller/inform/base'
23
- require_relative 'story_teller/model_adapter'
24
- require_relative 'story_teller/inform/models'
25
- require_relative 'story_teller/ephemeral_adapter'
26
- require_relative 'story_teller/core'
22
+ require_relative 'story_teller/builtins'
23
+ require_relative 'story_teller/stdlib'
24
+ require_relative 'story_teller/logging'
25
+ require_relative 'story_teller/prototype'
26
+ require_relative 'story_teller/command'
27
+ require_relative 'story_teller/history'
28
+ require_relative 'story_teller/events'
29
+ require_relative 'story_teller/grammar_parser'
30
+ require_relative 'story_teller/kernel'
31
+ require_relative 'story_teller/mixins'
32
+ require_relative 'story_teller/helpers'
33
+ require_relative 'story_teller/io'
34
+ require_relative 'story_teller/publication'
35
+ require_relative 'story_teller/context'
36
+ require_relative 'story_teller/privileges'
37
+ require_relative 'story_teller/world_tree'
38
+ require_relative 'story_teller/library'
39
+ require_relative 'story_teller/engine'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inform-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nels Nelson
@@ -29,28 +29,28 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 4.1.1
32
+ version: 4.1.2
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 4.1.1
39
+ version: 4.1.2
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: inform6lib
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.1.0
46
+ version: 0.1.2
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 0.1.0
53
+ version: 0.1.2
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: logger
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -95,10 +95,8 @@ files:
95
95
  - lib/story_teller/color.rb
96
96
  - lib/story_teller/command.rb
97
97
  - lib/story_teller/context.rb
98
- - lib/story_teller/core.rb
99
98
  - lib/story_teller/daemon.rb
100
99
  - lib/story_teller/engine.rb
101
- - lib/story_teller/ephemeral_adapter.rb
102
100
  - lib/story_teller/events.rb
103
101
  - lib/story_teller/experimental/handler_dsl.rb
104
102
  - lib/story_teller/experimental/reverse_engineer_class.rb
@@ -106,7 +104,6 @@ files:
106
104
  - lib/story_teller/helpers.rb
107
105
  - lib/story_teller/history.rb
108
106
  - lib/story_teller/inflector.rb
109
- - lib/story_teller/inform/base.rb
110
107
  - lib/story_teller/inform/ephemeral/link.rb
111
108
  - lib/story_teller/inform/ephemeral/module.rb
112
109
  - lib/story_teller/inform/ephemeral/object.rb
@@ -122,8 +119,8 @@ files:
122
119
  - lib/story_teller/library/location.rb
123
120
  - lib/story_teller/logging.rb
124
121
  - lib/story_teller/mixins.rb
125
- - lib/story_teller/model_adapter.rb
126
122
  - lib/story_teller/plurals.rb
123
+ - lib/story_teller/privileges.rb
127
124
  - lib/story_teller/prototype.rb
128
125
  - lib/story_teller/publication.rb
129
126
  - lib/story_teller/session.rb
@@ -153,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
150
  - !ruby/object:Gem::Version
154
151
  version: '0'
155
152
  requirements: []
156
- rubygems_version: 4.0.9
153
+ rubygems_version: 4.0.11
157
154
  specification_version: 4
158
155
  summary: StoryTeller Engine for Ruby.
159
156
  test_files: []
@@ -1,38 +0,0 @@
1
- # lib/story_teller/core.rb
2
- # encoding: utf-8
3
- # frozen_string_literal: false
4
-
5
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
6
- #
7
- # This file is part of the StoryTeller.
8
- #
9
- # The StoryTeller is free software: you can redistribute it and/or
10
- # modify it under the terms of the GNU General Public License as published
11
- # by the Free Software Foundation, either version 3 of the License, or
12
- # (at your option) any later version.
13
- #
14
- # The StoryTeller is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- # GNU General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU General Public License
20
- # along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
21
-
22
- require_relative 'builtins'
23
- require_relative 'stdlib'
24
- require_relative 'logging'
25
- require_relative 'prototype'
26
- require_relative 'command'
27
- require_relative 'history'
28
- require_relative 'events'
29
- require_relative 'grammar_parser'
30
- require_relative 'kernel'
31
- require_relative 'mixins'
32
- require_relative 'helpers'
33
- require_relative 'io'
34
- require_relative 'publication'
35
- require_relative 'context'
36
- require_relative 'world_tree'
37
- require_relative 'library'
38
- require_relative 'engine'
@@ -1,40 +0,0 @@
1
- # lib/story_teller/ephemeral_adapter.rb
2
- # encoding: utf-8
3
- # frozen_string_literal: false
4
-
5
- # Copyright Nels Nelson 2008-2025 but freely usable (see license)
6
- #
7
- # This file is part of StoryTeller.
8
- #
9
- # StoryTeller is free software: you can redistribute it and/or
10
- # modify it under the terms of the GNU General Public License as published
11
- # by the Free Software Foundation, either version 3 of the License, or
12
- # (at your option) any later version.
13
- #
14
- # StoryTeller is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- # GNU General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU General Public License
20
- # along with StoryTeller. If not, see <http://www.gnu.org/licenses/>.
21
-
22
- # module StoryTeller
23
- module StoryTeller
24
- # module EphemeralAdapter
25
- module EphemeralAdapter
26
- Adapter = {
27
- name: :ephemeral,
28
- object_class: Inform::Ephemeral::Object,
29
- tag_class: Inform::Ephemeral::Tag,
30
- link_class: Inform::Ephemeral::Link,
31
- module_class: Inform::Ephemeral::Module
32
- }.freeze
33
-
34
- module_function
35
-
36
- def register!
37
- StoryTeller::ModelAdapter.register!(Adapter)
38
- end
39
- end
40
- end