inform-runtime 1.0.4

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +623 -0
  3. data/README.md +185 -0
  4. data/Rakefile +65 -0
  5. data/config/database.yml +37 -0
  6. data/exe/inform.rb +6 -0
  7. data/game/config.yml +5 -0
  8. data/game/example.inf +76 -0
  9. data/game/example.rb +90 -0
  10. data/game/forms/example_form.rb +2 -0
  11. data/game/grammar/game_grammar.inf.rb +11 -0
  12. data/game/languages/english.rb +2 -0
  13. data/game/models/example_model.rb +2 -0
  14. data/game/modules/example_module.rb +9 -0
  15. data/game/rules/example_state.rb +2 -0
  16. data/game/scripts/example_script.rb +2 -0
  17. data/game/topics/example_topic.rb +2 -0
  18. data/game/verbs/game_verbs.rb +15 -0
  19. data/game/verbs/metaverbs.rb +2028 -0
  20. data/lib/runtime/articles.rb +138 -0
  21. data/lib/runtime/builtins.rb +359 -0
  22. data/lib/runtime/color.rb +145 -0
  23. data/lib/runtime/command.rb +470 -0
  24. data/lib/runtime/config.rb +48 -0
  25. data/lib/runtime/context.rb +78 -0
  26. data/lib/runtime/daemon.rb +266 -0
  27. data/lib/runtime/database.rb +500 -0
  28. data/lib/runtime/events.rb +771 -0
  29. data/lib/runtime/experimental/handler_dsl.rb +175 -0
  30. data/lib/runtime/game.rb +74 -0
  31. data/lib/runtime/game_loader.rb +132 -0
  32. data/lib/runtime/grammar_parser.rb +553 -0
  33. data/lib/runtime/helpers.rb +177 -0
  34. data/lib/runtime/history.rb +45 -0
  35. data/lib/runtime/inflector.rb +195 -0
  36. data/lib/runtime/io.rb +174 -0
  37. data/lib/runtime/kernel.rb +450 -0
  38. data/lib/runtime/library.rb +59 -0
  39. data/lib/runtime/library_loader.rb +135 -0
  40. data/lib/runtime/link.rb +158 -0
  41. data/lib/runtime/logging.rb +197 -0
  42. data/lib/runtime/mixins.rb +570 -0
  43. data/lib/runtime/module.rb +202 -0
  44. data/lib/runtime/object.rb +761 -0
  45. data/lib/runtime/options.rb +104 -0
  46. data/lib/runtime/persistence.rb +292 -0
  47. data/lib/runtime/plurals.rb +60 -0
  48. data/lib/runtime/prototype.rb +307 -0
  49. data/lib/runtime/publication.rb +92 -0
  50. data/lib/runtime/runtime.rb +321 -0
  51. data/lib/runtime/session.rb +202 -0
  52. data/lib/runtime/stdlib.rb +604 -0
  53. data/lib/runtime/subscription.rb +47 -0
  54. data/lib/runtime/tag.rb +287 -0
  55. data/lib/runtime/tree.rb +204 -0
  56. data/lib/runtime/version.rb +24 -0
  57. data/lib/runtime/world_tree.rb +69 -0
  58. data/lib/runtime.rb +35 -0
  59. metadata +199 -0
data/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # Inform Runtime
2
+
3
+ [![License](https://img.shields.io/badge/license-GPLv3-blue.svg?style=flat)](license-gpl)
4
+
5
+
6
+
7
+ **The Inform Runtime** for Ruby is a command-line interface software
8
+ runtime program for playing interactive-fiction games which use the
9
+ [Inform 6 Ruby Port].
10
+
11
+ The Inform Runtime for Ruby is intended to simply provide the barest
12
+ minimum facilities required by the Inform 6 Library Ruby Port software to
13
+ function in the context of a game play specified by a game directory or
14
+ file. It does not attempt to replicate a byte code interpreter runtime
15
+ like frotz.
16
+
17
+
18
+ ## Install mise-en-place
19
+
20
+ The [mise] CLI tool used to manage multiple runtime versions.
21
+
22
+ See: https://mise.jdx.dev/getting-started.html
23
+
24
+ ```sh
25
+ curl https://mise.run/zsh | sh
26
+ mise --version
27
+ ```
28
+
29
+
30
+ ## Install required runtime software
31
+
32
+ ```sh
33
+ mise install
34
+ ```
35
+
36
+ Now install the `bundler` for managing project dependencies.
37
+
38
+ ```sh
39
+ gem install bundler
40
+ gem update --system
41
+ ```
42
+
43
+
44
+ Download and install the latest version of [PostgreSQL].
45
+
46
+
47
+ ## Setup
48
+
49
+ Install some gem dependencies.
50
+
51
+ ```sh
52
+ bundle update --bundler
53
+ bundle install
54
+ ```
55
+
56
+
57
+ ## Run
58
+
59
+ Execute the `inform.rb` program. It will play the included example game.
60
+
61
+ ```sh
62
+ bundle exec inform.rb
63
+ ```
64
+
65
+ ```
66
+ Welcome to...
67
+
68
+ EXAMPLE
69
+ An Interactive Example
70
+ Copyright (c) 2025 by Nels N. Nelson.
71
+ Release 1 / Serial number 251006 / inform.rb v1.0.3 Library 6/11N
72
+
73
+ Field
74
+ You are standing in a field in front of a small 19th century house which stands just to the east of you. The house hardly stands up to the stiff wind rolling down from the north.
75
+ You can see a small toy top here.
76
+
77
+ >quit
78
+ Are you sure you want to quit? yes
79
+ [Hit enter to exit.]
80
+ ```
81
+
82
+
83
+ ## Linting
84
+
85
+ ```sh
86
+ bundle exec rake lint
87
+ ```
88
+
89
+
90
+ ## Testing
91
+
92
+ ```sh
93
+ bundle exec rake test
94
+ ```
95
+
96
+
97
+ ## Project file tree
98
+
99
+ Here is a bird's-eye view of the project layout.
100
+
101
+ ```sh
102
+ # date && tree -A -I "game|logs|vendor|tmp|Gemfile.lock"
103
+ Tue Oct 14 19:01:27 CDT 2025
104
+ .
105
+ ├── config
106
+ │ └── database.yml
107
+ ├── CONTRIBUTING.md
108
+ ├── exe
109
+ │ └── inform.rb
110
+ ├── Gemfile
111
+ ├── inform-runtime-1.0.3.gem
112
+ ├── inform-runtime.gemspec
113
+ ├── lib
114
+ │ ├── runtime
115
+ │ │ ├── articles.rb
116
+ │ │ ├── builtins.rb
117
+ │ │ ├── color.rb
118
+ │ │ ├── command.rb
119
+ │ │ ├── config.rb
120
+ │ │ ├── context.rb
121
+ │ │ ├── daemon.rb
122
+ │ │ ├── database.rb
123
+ │ │ ├── events.rb
124
+ │ │ ├── experimental
125
+ │ │ │ └── handler_dsl.rb
126
+ │ │ ├── game_loader.rb
127
+ │ │ ├── game.rb
128
+ │ │ ├── grammar_parser.rb
129
+ │ │ ├── helpers.rb
130
+ │ │ ├── history.rb
131
+ │ │ ├── inflector.rb
132
+ │ │ ├── io.rb
133
+ │ │ ├── kernel.rb
134
+ │ │ ├── library_loader.rb
135
+ │ │ ├── library.rb
136
+ │ │ ├── link.rb
137
+ │ │ ├── logging.rb
138
+ │ │ ├── mixins.rb
139
+ │ │ ├── module.rb
140
+ │ │ ├── object.rb
141
+ │ │ ├── options.rb
142
+ │ │ ├── persistence.rb
143
+ │ │ ├── plurals.rb
144
+ │ │ ├── prototype.rb
145
+ │ │ ├── publication.rb
146
+ │ │ ├── runtime.rb
147
+ │ │ ├── session.rb
148
+ │ │ ├── stdlib.rb
149
+ │ │ ├── subscription.rb
150
+ │ │ ├── tag.rb
151
+ │ │ ├── tree.rb
152
+ │ │ ├── version.rb
153
+ │ │ └── world_tree.rb
154
+ │ └── runtime.rb
155
+ ├── LICENSE
156
+ ├── Rakefile
157
+ ├── README.md
158
+ ├── roller2.jpg
159
+ ├── scripts
160
+ │ ├── backup.rb
161
+ │ ├── clone.rb
162
+ │ ├── delete.rb
163
+ │ ├── init.rb
164
+ │ ├── rebuild.rb
165
+ │ └── restore.rb
166
+ └── spec
167
+ ├── game_spec.rb
168
+ ├── inform_spec.rb
169
+ ├── inform_system_spec.rb
170
+ ├── object_spec.rb
171
+ ├── parser_spec.rb
172
+ ├── spec_helper.rb
173
+ ├── verblib_spec.rb
174
+ └── verify_gem_spec.rb
175
+
176
+ 7 directories, 63 files
177
+ ```
178
+
179
+ Thanks!
180
+
181
+ [Inform 6 Ruby Port]: https://gitlab.com/nelsnelson/inform6-ruby
182
+ [license-gpl]: https://gitlab.com/nelsnelson/inform6/blob/master/LICENSE
183
+ [mise]: https://mise.jdx.dev/
184
+ [PostgreSQL]: https://postgresql.org/download
185
+
data/Rakefile ADDED
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # -*- mode: ruby -*-
5
+ # vi: set ft=ruby :
6
+
7
+ require 'rake'
8
+ require 'rake/clean'
9
+
10
+ unless defined?(InformRuntime::PROJECT)
11
+ # Ensure InformRuntime module constants
12
+ module InformRuntime
13
+ PROJECT = File.basename(__dir__)
14
+ end
15
+ end
16
+
17
+ load "#{InformRuntime::PROJECT}.gemspec"
18
+
19
+ CLEAN.add File.join('tmp', '**', '*'), 'tmp'
20
+ CLOBBER.add '*.gem', 'pkg'
21
+
22
+ task default: %i[package]
23
+
24
+ desc 'Run the rubocop linter'
25
+ task :lint do
26
+ system('bundle', 'exec', 'rubocop') or abort
27
+ end
28
+
29
+ desc 'Run the spec tests'
30
+ task :test do
31
+ system('bundle', 'exec', 'rspec', '--format=documentation') or abort
32
+ end
33
+ task test: :lint
34
+
35
+ desc 'Explode the gem'
36
+ task :explode do
37
+ puts "Installing gem into the ./tmp directory..."
38
+ gems = Dir['*.gem']
39
+ raise 'No .gem files found; to build, run: bundle exec rake' if gems.empty?
40
+ system('gem', 'install', '--no-document', '--install-dir=tmp', *gems) or abort
41
+ end
42
+ task explode: :clean
43
+
44
+ desc 'Package the gem'
45
+ task :package do
46
+ system('gem', 'build') or abort
47
+ end
48
+ task package: %i[clean clobber test]
49
+
50
+ desc 'Verify the gem'
51
+ task :verify do
52
+ system('bundle', 'exec', 'rspec', 'spec/verify_gem_spec.rb') or abort
53
+ system('bundle', 'exec', 'rake', 'clean')
54
+ end
55
+ task verify: :explode
56
+
57
+ desc 'Publish the gem'
58
+ task :publish do
59
+ system('gem', 'push', latest_gem) or abort
60
+ end
61
+ task publish: :verify
62
+
63
+ def latest_gem
64
+ Dir["#{InformRuntime::PROJECT}*.gem"].max_by { |p| File.mtime(p) }
65
+ end
@@ -0,0 +1,37 @@
1
+
2
+ default:
3
+ adapter: postgres
4
+ database: postgres
5
+ username: postgres
6
+ host: localhost
7
+ pool: 5
8
+
9
+ development:
10
+ adapter: postgres
11
+ database: example
12
+ username: example
13
+ password: example
14
+ host: localhost
15
+ pool: 5
16
+ timeout: 5000
17
+
18
+ test:
19
+ adapter: sqlite
20
+
21
+ docker:
22
+ adapter: postgres
23
+ database: example
24
+ username: example
25
+ password: example
26
+ host: postgres
27
+ pool: 5
28
+ timeout: 5000
29
+
30
+ production:
31
+ adapter: postgres
32
+ database: example
33
+ username: example
34
+ password: example
35
+ host: localhost
36
+ pool: 5
37
+ timeout: 5000
data/exe/inform.rb ADDED
@@ -0,0 +1,6 @@
1
+ #! /usr/bin/env ruby
2
+ # frozen_string_literal: false
3
+
4
+ require_relative '../lib/runtime'
5
+
6
+ Object.new.extend(Inform::App).main
data/game/config.yml ADDED
@@ -0,0 +1,5 @@
1
+ # Configuration for game module
2
+
3
+ ---
4
+ database_name: example
5
+ environment: production
data/game/example.inf ADDED
@@ -0,0 +1,76 @@
1
+
2
+ ! ----------------------------------------------------------------------------
3
+ ! Example
4
+ ! ----------------------------------------------------------------------------
5
+
6
+ ! DEBUG = true
7
+ Constant Story = "EXAMPLE";
8
+ Constant Headline = "^An Interactive Example^
9
+ Copyright (c) 2025 by Nels N. Nelson.^";
10
+
11
+ Replace DrawStatusLine;
12
+
13
+ Include "Parser";
14
+ Include "VerbLib";
15
+
16
+ Object Field "Field"
17
+ with description
18
+ "You are standing in a field. A small 19th century house stands
19
+ to the east, hardly standing up to the stiff wind rolling down
20
+ from the north.",
21
+ e_to HouseFoyer,
22
+ w_to Shingle
23
+ has light;
24
+
25
+ Object -> "small toy top"
26
+ with name 'small' 'toy' 'top',
27
+ before [;
28
+ Examine:
29
+ print "A totem, somehow familiar, made of brass";
30
+ if (self in player) {
31
+ print " and heavy in your hand";
32
+ }
33
+ ".";
34
+ ];
35
+
36
+ Object HouseFoyer "Foyer"
37
+ with description
38
+ "You stand in the foyer of this
39
+ ancient structure. A draft swirls through
40
+ the hallway to the east.",
41
+ out_to Field,
42
+ w_to Field
43
+ has light;
44
+
45
+ Object Shingle "Shingle"
46
+ with description
47
+ "You seem to be only a small child
48
+ playing on a sea-shore, and diverting yourself
49
+ in finding a smoother pebble or a prettier shell
50
+ than ordinary, whilst the great ocean of
51
+ truth lies all undiscovered before you.",
52
+ e_to Field
53
+ has light;
54
+
55
+ [ Initialise;
56
+ location = Field;
57
+ "^^^^^Welcome to...^";
58
+ ];
59
+
60
+ [ DrawStatusLine;
61
+ @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
62
+ spaces (0->33)-1;
63
+ @set_cursor 1 2; PrintShortName(location);
64
+ @set_cursor 1 60; print "(as ";
65
+ @print_obj player;
66
+ print ")"; ! There ya are.
67
+ @set_cursor 1 1; style roman; @set_window 0;
68
+ ];
69
+
70
+ Include "Grammar";
71
+
72
+ Verb meta 'example'
73
+ * -> Example;
74
+ Verb 'smile'
75
+ * -> Smile;
76
+
data/game/example.rb ADDED
@@ -0,0 +1,90 @@
1
+
2
+ # ----------------------------------------------------------------------------
3
+ # Example
4
+ # ----------------------------------------------------------------------------
5
+
6
+ # DEBUG = true
7
+ Story = "EXAMPLE"
8
+ Headline = "\nAn Interactive Example\n" \
9
+ "Copyright (c) 2025 by Nels N. Nelson.\n"
10
+ Release = 1
11
+
12
+ def DrawStatusLine; end
13
+
14
+ Include "Parser"
15
+ Include "VerbLib"
16
+
17
+ Field = Object("Field") {
18
+ with {
19
+ description "You are standing in a field in " \
20
+ "front of a small 19th century house which " \
21
+ "stands just to the east of you. The house " \
22
+ "hardly stands up to the stiff wind rolling " \
23
+ "down from the north."
24
+ e_to :HouseFoyer
25
+ w_to :Shingle
26
+ }
27
+ has :light
28
+ }
29
+
30
+ # Note that the "with" directive here is vestigial and
31
+ # can be discarded altogether, but is supported for
32
+ # ease of transition/adoption.
33
+ #
34
+ # Field > Object("small toy top") {
35
+ # with {
36
+ # def before_examine
37
+ # "A totem, somehow familiar, made of brass" +
38
+ # (self.parent == player ? " and heavy in your hand" : '') + "."
39
+ # end
40
+ # weight 15 # grams
41
+ # }
42
+ # }
43
+ Field > Object("small toy top") {
44
+ def before_examine
45
+ print "A totem, somehow familiar, made of brass"
46
+ print " and heavy in your hand" if self.parent == player
47
+ "."
48
+ end
49
+ weight 15 # grams
50
+ }
51
+
52
+ HouseFoyer = Object("Foyer") {
53
+ with {
54
+ description "You stand in the foyer of this " \
55
+ "ancient structure. A draft swirls through " \
56
+ "the hallway to the east."
57
+ out_to :Field; w_to :Field
58
+ }
59
+ has :light
60
+ }
61
+
62
+ Shingle = Object("Shingle") {
63
+ with {
64
+ description "You seem to be only a small child " \
65
+ "playing on a sea-shore, and diverting yourself " \
66
+ "in finding a smoother pebble or a prettier shell " \
67
+ "than ordinary, whilst the great ocean of " \
68
+ "truth lies all undiscovered before you."
69
+ e_to :Field
70
+ }
71
+ has :light
72
+ }
73
+
74
+ class InformLibrary
75
+ def Initialise
76
+ @location = Field
77
+ "\n\n\n\n\nWelcome to...\n"
78
+ end
79
+ end
80
+
81
+ Include "Grammar"
82
+
83
+ Inform::Grammar <<~EOT
84
+ Verb meta 'example'
85
+ * -> Example;
86
+ Verb 'smile'
87
+ * -> Smile;
88
+ EOT
89
+
90
+ # log.info "Finished loading example game file: #{__FILE__} #<#{self.class}:#{self.object_id}>"
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ Verb meta 'library'
5
+ * 'methods' -> LibraryMethods;
6
+
7
+ Verb meta 'test'
8
+ * -> Test
9
+ * special -> Test
10
+ * number special -> Test;
11
+
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # The Huggable module
5
+ module Huggable
6
+ def life_hug
7
+ ":-)"
8
+ end
9
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+
4
+ # The Inform module
5
+ module Inform
6
+ # The Verb module
7
+ module Verbs
8
+ def ExampleSub
9
+ "This is just an example."
10
+ end
11
+ def SmileSub
12
+ "You smile."
13
+ end
14
+ end
15
+ end