story-teller 1.1.3
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 +7 -0
- data/LICENSE +623 -0
- data/README.md +188 -0
- data/Rakefile +58 -0
- data/config/database.yml +37 -0
- data/exe/inform.rb +6 -0
- data/game/config.yml +5 -0
- data/game/example.inf +90 -0
- data/game/example.rb +105 -0
- data/game/forms/example_form.rb +2 -0
- data/game/grammar/admin.inf.rb +185 -0
- data/game/grammar/builder.inf.rb +310 -0
- data/game/grammar/game_grammar.inf.rb +6 -0
- data/game/grammar/meta.inf.rb +41 -0
- data/game/languages/english.rb +571 -0
- data/game/models/example_model.rb +2 -0
- data/game/modules/example_module.rb +9 -0
- data/game/modules/parser_extensions.rb +264 -0
- data/game/rules/example_state.rb +2 -0
- data/game/scripts/example_script.rb +2 -0
- data/game/topics/example_topic.rb +2 -0
- data/game/verbs/game_verbs.rb +35 -0
- data/game/verbs/metaverbs.rb +2066 -0
- data/lib/story_teller/application.rb +82 -0
- data/lib/story_teller/cli.rb +35 -0
- data/lib/story_teller/color.rb +144 -0
- data/lib/story_teller/config.rb +61 -0
- data/lib/story_teller/curses_adapter.rb +30 -0
- data/lib/story_teller/database.rb +527 -0
- data/lib/story_teller/game/loader.rb +276 -0
- data/lib/story_teller/game.rb +22 -0
- data/lib/story_teller/inform/models.rb +42 -0
- data/lib/story_teller/inform/relational/link.rb +239 -0
- data/lib/story_teller/inform/relational/module.rb +203 -0
- data/lib/story_teller/inform/relational/object.rb +546 -0
- data/lib/story_teller/inform/relational/tag.rb +152 -0
- data/lib/story_teller/options.rb +151 -0
- data/lib/story_teller/persistence.rb +340 -0
- data/lib/story_teller/player_character.rb +99 -0
- data/lib/story_teller/privileges.rb +55 -0
- data/lib/story_teller/runtime.rb +381 -0
- data/lib/story_teller/snapshots.rb +412 -0
- data/lib/story_teller/terminal.rb +58 -0
- data/lib/story_teller/version.rb +24 -0
- data/lib/story_teller_cli.rb +34 -0
- metadata +158 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# lib/story/application.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
|
+
# module StoryTeller
|
|
23
|
+
module StoryTeller
|
|
24
|
+
# The Application class is the host composition root for a StoryTeller runtime.
|
|
25
|
+
class Application
|
|
26
|
+
attr_reader :options, :runtime
|
|
27
|
+
|
|
28
|
+
def initialize(options = StoryTeller::Config.defaults)
|
|
29
|
+
@options = options
|
|
30
|
+
configure_engine
|
|
31
|
+
configure_context
|
|
32
|
+
@runtime = StoryTeller::Runtime.instance(@options)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def load_game
|
|
36
|
+
runtime.persistence.reset! if options[:reset_db_each_session]
|
|
37
|
+
runtime.load_game
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def play_game
|
|
41
|
+
runtime.manage_privileges
|
|
42
|
+
runtime.play_game
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def run
|
|
46
|
+
load_game
|
|
47
|
+
play_game
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def configure_engine
|
|
53
|
+
StoryTeller::Engine.executable = main_gem_spec_executable || @options[:executable]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def main_gem_spec_executable
|
|
57
|
+
require 'rubygems'
|
|
58
|
+
|
|
59
|
+
gem_spec = Gem.loaded_specs[File.basename(StoryTeller::Runtime.project_dir_path)]
|
|
60
|
+
(gem_spec&.executables || []).first
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def configure_context
|
|
64
|
+
definition = invocation_context
|
|
65
|
+
return if definition.nil?
|
|
66
|
+
|
|
67
|
+
Inform::Context.set(definition)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def invocation_properties
|
|
71
|
+
@invocation_properties ||= @options.fetch(:properties, '').split.map(&:to_sym)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def invocation_context
|
|
75
|
+
return nil if invocation_properties.empty?
|
|
76
|
+
|
|
77
|
+
Struct.new(*invocation_properties)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
# class Application
|
|
81
|
+
end
|
|
82
|
+
# module StoryTeller
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# lib/story_teller/cli.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
|
+
# module StoryTeller
|
|
23
|
+
module StoryTeller
|
|
24
|
+
# module Cli
|
|
25
|
+
module Cli
|
|
26
|
+
include StoryTeller::Options
|
|
27
|
+
|
|
28
|
+
def main(args = parse_arguments(defaults: StoryTeller::Config.defaults))
|
|
29
|
+
Logging.log_level = args[:log_level]
|
|
30
|
+
application = StoryTeller::Application.new(args)
|
|
31
|
+
application.load_game
|
|
32
|
+
application.play_game
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# lib/story_teller/color.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
|
+
# The StoryTeller module
|
|
23
|
+
module StoryTeller
|
|
24
|
+
# The Color module
|
|
25
|
+
module Color
|
|
26
|
+
StyleCodes = {
|
|
27
|
+
plain: [
|
|
28
|
+
"\e[0m", "\e[0m"],
|
|
29
|
+
bold: [
|
|
30
|
+
"\e[1m", "\e[22m"],
|
|
31
|
+
italic: [
|
|
32
|
+
"\e[3m", "\e[23m"],
|
|
33
|
+
underline: [
|
|
34
|
+
"\e[4m", "\e[24m"],
|
|
35
|
+
blink: [
|
|
36
|
+
"\e[5m", "\e[25m"],
|
|
37
|
+
flash: [
|
|
38
|
+
"\e[6m", "\e[26m"],
|
|
39
|
+
inverse: [
|
|
40
|
+
"\e[7m", "\e[27m"],
|
|
41
|
+
hidden: [
|
|
42
|
+
"\e[8m", "\e[28m"],
|
|
43
|
+
strikethrough: [
|
|
44
|
+
"\e[9m", "\e[29m"]
|
|
45
|
+
}.freeze
|
|
46
|
+
|
|
47
|
+
ColorCodes = {
|
|
48
|
+
default: [
|
|
49
|
+
"\e[0m", "\e[0m"],
|
|
50
|
+
black: [
|
|
51
|
+
"\e[30m", "\e[39m"],
|
|
52
|
+
black_on_white: [
|
|
53
|
+
"\e[30m", "\e[39m"],
|
|
54
|
+
red: [
|
|
55
|
+
"\e[31m", "\e[39m"],
|
|
56
|
+
green: [
|
|
57
|
+
"\e[32m", "\e[39m"],
|
|
58
|
+
yellow: [
|
|
59
|
+
"\e[33m", "\e[39m"],
|
|
60
|
+
blue: [
|
|
61
|
+
"\e[34m", "\e[39m"],
|
|
62
|
+
purple: [
|
|
63
|
+
"\e[35m", "\e[39m"],
|
|
64
|
+
magenta: [
|
|
65
|
+
"\e[35m", "\e[39m"],
|
|
66
|
+
cyan: [
|
|
67
|
+
"\e[36m", "\e[39m"],
|
|
68
|
+
white: [
|
|
69
|
+
"\e[37m", "\e[39m"]
|
|
70
|
+
}.freeze
|
|
71
|
+
|
|
72
|
+
BackgroundColorCodes = {
|
|
73
|
+
default: [
|
|
74
|
+
"\e[0m", "\e[0m"],
|
|
75
|
+
black: [
|
|
76
|
+
"\e[40m", "\e[49m"],
|
|
77
|
+
red: [
|
|
78
|
+
"\e[41m", "\e[49m"],
|
|
79
|
+
green: [
|
|
80
|
+
"\e[42m", "\e[49m"],
|
|
81
|
+
yellow: [
|
|
82
|
+
"\e[43m", "\e[49m"],
|
|
83
|
+
blue: [
|
|
84
|
+
"\e[44m", "\e[49m"],
|
|
85
|
+
purple: [
|
|
86
|
+
"\e[45m", "\e[49m"],
|
|
87
|
+
magenta: [
|
|
88
|
+
"\e[45m", "\e[49m"],
|
|
89
|
+
cyan: [
|
|
90
|
+
"\e[46m", "\e[49m"],
|
|
91
|
+
white: [
|
|
92
|
+
"\e[47m", "\e[49m"]
|
|
93
|
+
}.freeze
|
|
94
|
+
|
|
95
|
+
# Text style and color for terminals
|
|
96
|
+
def style(style, text = nil)
|
|
97
|
+
code = (StyleCodes[style] || StyleCodes[:plain]).first
|
|
98
|
+
return code + text + (StyleCodes[style] || StyleCodes[:plain]).last unless text.nil?
|
|
99
|
+
print code
|
|
100
|
+
end
|
|
101
|
+
def un_style(style)
|
|
102
|
+
print((StyleCodes[style] || StyleCodes[:plain]).last)
|
|
103
|
+
end
|
|
104
|
+
alias unstyle un_style
|
|
105
|
+
def color(color, text = nil)
|
|
106
|
+
code = (ColorCodes[color] || ColorCodes[:default]).first
|
|
107
|
+
return code + text + (ColorCodes[color] || ColorCodes[:default]).last unless text.nil?
|
|
108
|
+
print code
|
|
109
|
+
end
|
|
110
|
+
def un_color(color)
|
|
111
|
+
print((ColorCodes[color] || ColorCodes[:default]).last)
|
|
112
|
+
end
|
|
113
|
+
alias uncolor un_color
|
|
114
|
+
def background_color(color, text = nil)
|
|
115
|
+
code = (BackgroundColorCodes[color] || BackgroundColorCodes[:default]).first
|
|
116
|
+
return code + text + (BackgroundColorCodes[color] || BackgroundColorCodes[:default]).last unless text.nil?
|
|
117
|
+
print code
|
|
118
|
+
end
|
|
119
|
+
alias bgcolor background_color
|
|
120
|
+
def un_background_color(color)
|
|
121
|
+
print((BackgroundColorCodes[color] || BackgroundColorCodes[:default]).last)
|
|
122
|
+
end
|
|
123
|
+
alias unbgcolor un_background_color
|
|
124
|
+
|
|
125
|
+
NearestColor = {
|
|
126
|
+
red: %i[
|
|
127
|
+
crimson brick salmon coral],
|
|
128
|
+
yellow: %i[
|
|
129
|
+
golden orange],
|
|
130
|
+
green: %i[
|
|
131
|
+
seagreen teal forestgreen],
|
|
132
|
+
blue: %i[
|
|
133
|
+
aqua cyan skyblue turqoise],
|
|
134
|
+
magenta: %i[
|
|
135
|
+
lavender fuchsia indigo orchid plum purple violet]
|
|
136
|
+
}.freeze
|
|
137
|
+
|
|
138
|
+
def nearest_color(color)
|
|
139
|
+
colors = NearestColor.select { |_, v| v.include?(color) }
|
|
140
|
+
return colors.first.first unless colors.empty?
|
|
141
|
+
:white
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# lib/story/config.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
|
+
# module StoryTeller
|
|
23
|
+
module StoryTeller
|
|
24
|
+
# module Config
|
|
25
|
+
module Config
|
|
26
|
+
module_function
|
|
27
|
+
|
|
28
|
+
def project_dir_path
|
|
29
|
+
@project_dir_path ||= File.expand_path(File.join('..', '..'), __dir__)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def default_game_dir_name
|
|
33
|
+
'game'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def default_game_dir_path
|
|
37
|
+
File.join(project_dir_path, default_game_dir_name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
DEFAULTS = {
|
|
41
|
+
app_name: 'StoryTeller',
|
|
42
|
+
executable: 'inform.rb',
|
|
43
|
+
log_level: Logger::INFO,
|
|
44
|
+
admin: false,
|
|
45
|
+
persist: false,
|
|
46
|
+
reset_db_each_session: true,
|
|
47
|
+
language: 'English',
|
|
48
|
+
default_word_wrap: 78,
|
|
49
|
+
history_limit: 100,
|
|
50
|
+
game_path: default_game_dir_path,
|
|
51
|
+
game_dir_name: default_game_dir_name,
|
|
52
|
+
game_grammar_module_name: 'grammar',
|
|
53
|
+
game_config_file_name: 'config.yml',
|
|
54
|
+
game_components: 'modules world models rules verbs languages' # This order is required
|
|
55
|
+
}.freeze
|
|
56
|
+
|
|
57
|
+
def defaults
|
|
58
|
+
DEFAULTS.dup
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# lib/story_teller/curses_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 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
|
+
# module StoryTeller
|
|
23
|
+
module StoryTeller
|
|
24
|
+
# class CursesAdapter
|
|
25
|
+
class CursesAdapter
|
|
26
|
+
def write(value)
|
|
27
|
+
Curses.addstr(value)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|