gamefic-sdk 2.5.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +40 -28
  4. data/bin/console +14 -14
  5. data/gamefic-sdk.gemspec +4 -4
  6. data/lib/gamefic-sdk/diagram.rb +23 -15
  7. data/lib/gamefic-sdk/scaffold.rb +15 -8
  8. data/lib/gamefic-sdk/server.rb +8 -8
  9. data/lib/gamefic-sdk/tasks/common.rb +15 -0
  10. data/lib/gamefic-sdk/tasks/ruby.rb +4 -4
  11. data/lib/gamefic-sdk/tasks/web.rb +22 -26
  12. data/lib/gamefic-sdk/tasks.rb +1 -0
  13. data/lib/gamefic-sdk/version.rb +3 -1
  14. data/scaffolds/library/__name__.gemspec.gf.erb +37 -12
  15. data/scaffolds/library/lib/__name__/version.rb.gf.erb +5 -0
  16. data/scaffolds/library/lib/__name__.rb.gf.erb +10 -0
  17. data/scaffolds/project/README.md.gf.erb +3 -3
  18. data/scaffolds/project/__name__/plot.rb.gf.erb +17 -0
  19. data/scaffolds/project/__name__/subplot.rb.gf.erb +12 -0
  20. data/scaffolds/project/main.rb.gf.erb +7 -6
  21. metadata +26 -43
  22. data/scaffolds/library/lib/__name__.rb +0 -5
  23. data/scaffolds/react/.babelrc +0 -3
  24. data/scaffolds/react/package.json.gf.erb +0 -34
  25. data/scaffolds/react/web/public/index.html.gf.erb +0 -11
  26. data/scaffolds/react/web/src/driver/development.js +0 -4
  27. data/scaffolds/react/web/src/driver/opal.rb +0 -7
  28. data/scaffolds/react/web/src/driver/production.js +0 -5
  29. data/scaffolds/react/web/src/index.js +0 -28
  30. data/scaffolds/react/web/src/scenes/Activity.jsx +0 -13
  31. data/scaffolds/react/web/src/scenes/Conclusion.jsx +0 -12
  32. data/scaffolds/react/web/src/scenes/MultipleChoice.jsx +0 -13
  33. data/scaffolds/react/web/src/scenes/Pause.jsx +0 -13
  34. data/scaffolds/react/web/src/scenes/index.js +0 -11
  35. data/scaffolds/react/web/src/style.css +0 -3
  36. data/scaffolds/react/webpack.config.js +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d5077a8c894877c7b1d5796e0bae8f22eba29232163f8bdd7b971c4f7d435c7
4
- data.tar.gz: 21586177dedd557bdb616eacad0fe7c8280a52b0fb9225c2d8115c9ad748d7d0
3
+ metadata.gz: 7d90eb96a94149551b573259fd78410c1f0332b0a5ecaa9d559cc091a8962629
4
+ data.tar.gz: 4547e88ec7f62bcbe08d60d6411461327d1ff9f27c50755c47135c98cb4b1806
5
5
  SHA512:
6
- metadata.gz: 7953c0cf54322ab0d263f6c5100d71cf4b6e086cfff04cc47eb7282212f04eaeab431d67e2aab9eae1a2d438a2a0ef9bc0de8765e39f3f19b0b906de91a28583
7
- data.tar.gz: 8fca0a40c79f530ecbc141ef44d0783795ceebab81d7612688bb2058f3ae62dd1ff9a6f1f9babab21659ca0ac7abbb041e33f3ceb0b0f8645256edc873af4f8b
6
+ metadata.gz: '01081048d9c32716574e9ff9d906ee03cf07259875d608ea36fb73bea310440d43760c4d12f8e33159dfc346b31a33bf5eabf50c042c06bb169204aa5f8d98c4'
7
+ data.tar.gz: 6fadb23c6b9cfeeb855bfb082a932ae6abde7c722ebb194d20b3902900d8c50b679ce52e4205a04d6ac7544386e8c41baa47587d7323f9cfa9157ff43c8ea8f1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 3.0.1 - April 10, 2024
2
+ - Updates to README in project scaffold
3
+
4
+ ## 3.0.0 - January 27, 2024
5
+ - Deprecate broken/redundant commands
6
+ - Improved serialization
7
+ - Queries use proxies for static entities
8
+ - All scripted blocks get evaluated on stage
9
+ - Use react-gamefic for web scaffolds
10
+ - Modular projects and libraries
11
+ - New project scaffold
12
+
1
13
  ## 2.5.0 - February 11, 2023
2
14
  - Update dependencies
3
15
  - Improve tests and examples
data/README.md CHANGED
@@ -37,21 +37,26 @@ so there's not much to do yet. Enter `QUIT` to exit the game.
37
37
 
38
38
  ### The Script Code
39
39
 
40
- The main script for your narrative is `main.rb` in your project's root
41
- directory. It should look something like this:
40
+ The plot for your narrative is defined in the `plot.rb` file. It should look
41
+ something like this:
42
42
 
43
43
  ```ruby
44
- GAMEFIC_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
45
- require 'gamefic-standard'
44
+ module Example
45
+ class Plot < Gamefic::Plot
46
+ UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
46
47
 
47
- Gamefic.script do
48
- introduction do |actor|
49
- actor.tell "Hello, world!"
48
+ include Gamefic::Standard
49
+
50
+ script do
51
+ introduction do |actor|
52
+ actor.tell "Hello, world!"
53
+ end
54
+ end
50
55
  end
51
56
  end
52
57
  ```
53
58
 
54
- `GAMEFIC_UUID` is a globally unique identifier. It can be useful if you want to
59
+ `UUID` is a globally unique identifier. It can be useful if you want to
55
60
  add your game to online catalogs, such as the [Interactive Fiction Database](https://ifdb.tads.org/),
56
61
  but it's safe to delete if you don't need it.
57
62
 
@@ -61,26 +66,34 @@ developers should find it similar to Inform's Standard Rules. It defines common
61
66
  components like Rooms and Characters, along with in-game commands like `GO`,
62
67
  `GET`, and `DROP` to enable basic interactivity.
63
68
 
64
- `Gamefic.script` is where you write the story itself. In the starter project,
69
+ `script` is where you write the story itself. In the starter project,
65
70
  the only thing in the script is an introductory message.
66
71
 
67
72
  ### Modifying the Script
68
73
 
69
- Replace the contents of `main.rb` with the following:
74
+ Replace the contents of `plot.rb` with the following:
70
75
 
71
76
  ```ruby
72
- require 'gamefic-standard'
73
-
74
- Gamefic.script do
75
- @living_room = make Room, name: 'living room', description: 'This is your living room.'
76
- @bedroom = make Room, name: 'bedroom', description: 'This is your bedroom.'
77
- connect @living_room, @bedroom, 'north'
78
- @backpack = make Room, name: 'backpack', description: 'Your trusty backpack.', parent: @bedroom
79
- @book = make Room, name: 'book', description: 'Your favorite novel.', parent: @living_room
80
-
81
- introduction do |actor|
82
- actor.parent = @living_room
83
- actor.tell "You're in your house."
77
+ module Example
78
+ class Plot < Gamefic::Plot
79
+ UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
80
+
81
+ include Gamefic::Standard
82
+
83
+ seed do
84
+ @living_room = make Room, name: 'living room', description: 'This is your living room.'
85
+ @bedroom = make Room, name: 'bedroom', description: 'This is your bedroom.'
86
+ connect @living_room, @bedroom, 'north'
87
+ @backpack = make Room, name: 'backpack', description: 'Your trusty backpack.', parent: @bedroom
88
+ @book = make Room, name: 'book', description: 'Your favorite novel.', parent: @living_room
89
+ end
90
+
91
+ script do
92
+ introduction do |actor|
93
+ actor.parent = @living_room
94
+ actor.tell "You're in your house."
95
+ end
96
+ end
84
97
  end
85
98
  end
86
99
  ```
@@ -104,7 +117,7 @@ Test the game in a browser by starting a server:
104
117
  $ rake web:run
105
118
  ```
106
119
 
107
- Open `http://localhost:4342` to run the game in debug mode.
120
+ Open `http://localhost:9000` to run the game in debug mode.
108
121
 
109
122
  Build a standalone web game:
110
123
 
@@ -113,10 +126,9 @@ $ rake web:build
113
126
  ```
114
127
 
115
128
  The game's HTML file and related assets will be generated in the
116
- `builds/web/production` directory. The SDK uses
117
- [opal](https://github.com/opal/opal) to compile Ruby code to JavaScript, so the
118
- web build does not require a Ruby interpreter. Open `index.html` in a browser
119
- to play the game.
129
+ `web/build` directory. The SDK uses opal](https://github.com/opal/opal)
130
+ to compile Ruby code to JavaScript, so the web build does not require a
131
+ Ruby interpreter. Open `index.html` in a browser to play the game.
120
132
 
121
133
  Note: building the web app requires [Node.js](https://nodejs.org).
122
134
 
@@ -124,7 +136,7 @@ Note: building the web app requires [Node.js](https://nodejs.org).
124
136
 
125
137
  The gamefic-sdk repo includes several example projects that provide more
126
138
  complete demonstrations of Gamefic's features. To run an example, copy
127
- its `main.rb` file to your own project.
139
+ its `plot.rb` file to your own project.
128
140
 
129
141
  ### Learning More
130
142
 
data/bin/console CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "gamefic/sdk"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "gamefic-sdk"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/gamefic-sdk.gemspec CHANGED
@@ -24,17 +24,17 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.required_ruby_version = '>= 2.7.0'
26
26
 
27
- s.add_runtime_dependency 'gamefic', '~> 2.4'
28
- s.add_runtime_dependency 'gamefic-standard', '~> 2.4'
29
- s.add_runtime_dependency 'gamefic-tty', '~> 2.0', '>= 2.0.2'
27
+ s.add_runtime_dependency 'gamefic', '~> 3.0'
28
+ s.add_runtime_dependency 'gamefic-standard', '~> 3.0'
29
+ s.add_runtime_dependency 'gamefic-tty', '~> 3.0'
30
30
  s.add_runtime_dependency 'listen', '~> 3.0'
31
31
  s.add_runtime_dependency 'opal', '~> 1.1'
32
+ s.add_runtime_dependency 'puma', '~> 6'
32
33
  s.add_runtime_dependency 'sinatra', '~> 2'
33
34
  s.add_runtime_dependency 'thor', '~> 1.0'
34
35
 
35
36
  s.add_development_dependency 'bundler', '~> 2.0'
36
37
  s.add_development_dependency 'capybara', '~> 3.3'
37
- s.add_development_dependency 'puma', '~> 6'
38
38
  s.add_development_dependency 'rake', '~> 13.0'
39
39
  s.add_development_dependency 'rspec', '~> 3.0'
40
40
  s.add_development_dependency 'selenium-webdriver', '~> 4.2'
@@ -3,6 +3,8 @@ require 'json'
3
3
  module Gamefic
4
4
  module Sdk
5
5
  class Diagram
6
+ DIAGRAMMABLE = %w[entities responses verbs syntaxes commands scenes].freeze
7
+
6
8
  class Position
7
9
  attr_accessor :x, :y
8
10
 
@@ -53,31 +55,28 @@ module Gamefic
53
55
  end
54
56
 
55
57
  def entities
56
- plot.initial_state[:entities].map do |e|
57
- e.transform_keys do |k|
58
- str = k.to_s
59
- if str.start_with?('@')
60
- str[1..-1]
61
- else
62
- str
63
- end
64
- end
58
+ plot.entities.map do |ent|
59
+ {
60
+ name: ent.name,
61
+ type: ent.class,
62
+ parent: ent.parent&.name
63
+ }
65
64
  end
66
65
  end
67
66
 
68
- def actions
69
- plot.actions.map do |act|
67
+ def responses
68
+ plot.playbook.responses.map do |act|
70
69
  {
71
70
  verb: act.verb,
72
71
  meta: act.meta?,
73
- signature: act.signature
72
+ # signature: act.signature
74
73
  }
75
74
  end
76
75
  end
77
76
 
78
77
  def commands
79
78
  {
80
- actions: actions,
79
+ responses: responses,
81
80
  verbs: verbs,
82
81
  syntaxes: syntaxes
83
82
  }
@@ -92,14 +91,23 @@ module Gamefic
92
91
  {
93
92
  template: syn.template,
94
93
  command: syn.command,
95
- first_word: syn.first_word,
94
+ synonym: syn.synonym,
96
95
  verb: syn.verb
97
96
  }
98
97
  end
99
98
  end
100
99
 
100
+ def scenes
101
+ plot.scenebook.scenes.map do |scene|
102
+ {
103
+ name: scene.name,
104
+ type: scene.type
105
+ }
106
+ end
107
+ end
108
+
101
109
  def valid? type
102
- %w[rooms entities actions verbs syntaxes commands].include?(type)
110
+ DIAGRAMMABLE.include?(type)
103
111
  end
104
112
 
105
113
  private
@@ -8,8 +8,16 @@ module Gamefic
8
8
  module Sdk
9
9
  module Scaffold
10
10
  class Binder < OpenStruct
11
+ def camelcase string
12
+ string.split(/[_\s\-]+/).collect(&:capitalize).join
13
+ end
14
+
15
+ def snake_case string
16
+ string.split(/[_\s\-]+/).collect(&:downcase).join('_')
17
+ end
18
+
11
19
  def get_binding
12
- binding()
20
+ binding
13
21
  end
14
22
  end
15
23
 
@@ -23,7 +31,7 @@ module Gamefic
23
31
 
24
32
  def custom_copy origin, destination, data
25
33
  FileUtils.mkdir_p File.dirname(destination)
26
- if destination.end_with?('.gf.erb')
34
+ if origin.end_with?('.gf.erb')
27
35
  File.write destination[0..-8], render(origin, data)
28
36
  else
29
37
  FileUtils.cp_r origin, destination
@@ -33,18 +41,17 @@ module Gamefic
33
41
  def build name, destination
34
42
  dir = File.join(SCAFFOLDS_PATH, name)
35
43
  raise LoadError, "Scaffold `#{name}` does not exist" unless File.directory?(dir)
44
+
36
45
  path = Pathname.new('.').join(destination).realdirpath
37
46
  data = Binder.new(name: File.basename(path))
38
47
  files = Dir.glob(File.join(dir, '**', '*'), File::FNM_DOTMATCH).select { |entry| File.file?(entry) }
39
48
  map = {}
40
49
  files.each do |file|
41
- rename = File.join(File.dirname(file), File.basename(file).gsub('__name__', data.name))
50
+ rename = File.join(File.dirname(file), File.basename(file)).gsub('__name__', data.name)
42
51
  dst = File.join(destination, rename[dir.length..-1])
43
- if File.file?(dst)
44
- raise "Gamefic generation would overwrite existing file #{rename}"
45
- else
46
- map[file] = dst
47
- end
52
+ raise "Gamefic generation would overwrite existing file #{rename}" if File.file?(dst)
53
+
54
+ map[file] = dst
48
55
  end
49
56
  map.each_pair { |src, dst| custom_copy src, dst, data }
50
57
  system "cd #{Shellwords.escape(destination)} && bundle install"
@@ -1,11 +1,12 @@
1
1
  require 'sinatra/base'
2
2
  require 'yaml'
3
+ require 'puma'
3
4
 
4
5
  module Gamefic
5
6
  module Sdk
6
7
  class Server < Sinatra::Base
7
8
  set :port, 4342
8
- set :server, :webrick
9
+ set :server, :puma
9
10
 
10
11
  get '/' do
11
12
  File.read File.join(settings.public_folder, 'index.html')
@@ -31,19 +32,18 @@ module Gamefic
31
32
  end
32
33
 
33
34
  get '/snapshot' do
34
- content_type :json
35
- @@plot.save.to_json
35
+ content_type :text
36
+ snapshot = @@plot.save
37
+ snapshot
36
38
  end
37
39
 
38
40
  post '/restore' do
39
41
  content_type :json
40
- start_plot
41
42
  # The snapshot needs to be received as a JSON string because of issues
42
43
  # with IndifferentHash malforming arrays.
43
44
  snapshot = JSON.parse(params['snapshot'])
44
- @@plot.restore snapshot
45
- @@character.cue @@plot.default_scene
46
- @@plot.update
45
+ @@plot = Gamefic::Plot.restore snapshot
46
+ @@character = @@plot.players.first
47
47
  @@plot.ready
48
48
  @@character.output.to_json
49
49
  end
@@ -52,7 +52,7 @@ module Gamefic
52
52
  reset_features
53
53
  load File.join(settings.source_dir, 'main.rb')
54
54
  @@plot = Gamefic::Plot.new
55
- @@character = @@plot.get_player_character
55
+ @@character = @@plot.make_player_character
56
56
  @@plot.introduce @@character
57
57
  @@plot.ready
58
58
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
4
+ require 'yaml'
2
5
 
3
6
  module Gamefic
4
7
  module Sdk
@@ -15,6 +18,18 @@ module Gamefic
15
18
  def absolute_path
16
19
  @absolute_path ||= Pathname.new(directory).realpath.to_s
17
20
  end
21
+
22
+ def plot_class
23
+ GAMEFIC_PLOT_CLASS
24
+ end
25
+
26
+ def string_to_constant string
27
+ space = Object
28
+ string.split('::').each do |part|
29
+ space = space.const_get(part)
30
+ end
31
+ space
32
+ end
18
33
  end
19
34
  end
20
35
  end
@@ -16,7 +16,7 @@ module Gamefic
16
16
  #
17
17
  def run
18
18
  require_relative File.join(absolute_path, 'main')
19
- Gamefic::Tty::Engine.run
19
+ Gamefic::Tty::Engine.run(plot: plot_class.new)
20
20
  end
21
21
 
22
22
  # Build a distributable Ruby app.
@@ -36,8 +36,8 @@ module Gamefic
36
36
  files[rel] = Base64.encode64(Zlib::Deflate.deflate(File.read(full)))
37
37
  end
38
38
  program = program_code(files)
39
- FileUtils.mkdir_p File.join(absolute_path, 'builds', 'ruby')
40
- File.write(File.join(absolute_path, 'builds', 'ruby', "#{File.basename(absolute_path)}.rb"), program)
39
+ FileUtils.mkdir_p File.join(absolute_path, 'ruby', 'build')
40
+ File.write(File.join(absolute_path, 'ruby', 'build', "#{File.basename(absolute_path)}.rb"), program)
41
41
  end
42
42
 
43
43
  private
@@ -89,7 +89,7 @@ Dir.mktmpdir do |tmp|
89
89
  require 'gamefic-tty'
90
90
  require 'main'
91
91
  puts "\n"
92
- Gamefic::Tty::Engine.run
92
+ Gamefic::Tty::Engine.run(plot: #{plot_class}.new)
93
93
  end
94
94
  )
95
95
  end
@@ -11,42 +11,36 @@ module Gamefic
11
11
  # Generate a web app using NPM.
12
12
  #
13
13
  def generate
14
- Dir.chdir absolute_path do
15
- nv = `npm -v`.strip
16
- puts "Node version #{nv} detected. Preparing the web app..."
17
- Gamefic::Sdk::Scaffold.build 'react', '.'
18
- puts 'The web app scaffold is ready.'
19
- puts 'Run `npm install` to download the dependencies.'
14
+ puts "Node version #{check_for_npm} detected. Preparing the web app..."
15
+ web_path = File.join(absolute_path, 'web')
16
+ FileUtils.mkdir_p web_path
17
+ Dir.chdir web_path do
18
+ name = File.basename(absolute_path)
19
+ system 'npx', 'react-gamefic', '--name', name, '--class', 'GAMEFIC_PLOT_CLASS'
20
+ puts 'The web app is ready.'
21
+ puts 'Run `rake web:run` to start the app in dev mode.'
20
22
  end
21
- rescue Errno::ENOENT => e
22
- STDERR.puts "#{e.class}: #{e.message}"
23
- STDERR.puts "Web app generation requires Node (https://nodejs.org)."
24
23
  end
25
24
 
26
25
  # Run the web app in a server.
27
26
  #
28
27
  def run
29
28
  check_for_web_build
30
- build_development
31
- listener = Listen.to(File.join(absolute_path, 'web')) do |_mod, _add, _rem|
32
- build_development
29
+ Dir.chdir File.join(absolute_path, 'web') do
30
+ system 'npm start'
33
31
  end
34
- listener.start
35
- # @todo Get the public folder from a config?
36
- Gamefic::Sdk::Server.run! source_dir: absolute_path, public_folder: File.join(absolute_path, 'builds', 'web', 'development')
37
32
  end
38
33
 
39
34
  # Build a distributable web app using NPM.
40
35
  #
41
36
  def build
42
37
  check_for_web_build
43
- Dir.chdir absolute_path do
44
- pid = Process.spawn 'npm run build'
45
- Process.wait pid
38
+ Dir.chdir File.join(absolute_path, 'web') do
39
+ system 'npm run build'
46
40
  end
47
41
  rescue Errno::ENOENT => e
48
- STDERR.puts "#{e.class}: #{e.message}"
49
- STDERR.puts "Web app building requires Node (https://nodejs.org)."
42
+ warn "#{e.class}: #{e.message}"
43
+ warn 'Web app building requires Node (https://nodejs.org).'
50
44
  end
51
45
 
52
46
  private
@@ -55,7 +49,7 @@ module Gamefic
55
49
  #
56
50
  # @return [Boolean]
57
51
  def web_build_exists?
58
- File.exist?(File.join(absolute_path, 'package.json'))
52
+ File.exist?(File.join(absolute_path, 'web', 'package.json'))
59
53
  end
60
54
 
61
55
  # Check if a web build exists.
@@ -64,16 +58,18 @@ module Gamefic
64
58
  # @return [void]
65
59
  def check_for_web_build
66
60
  return if web_build_exists?
61
+
67
62
  puts 'This project does not appear to be configured for web builds.'
68
63
  puts 'Try running `rake web:generate` first.' if Rake::Task.task_defined?('web:generate')
69
64
  raise LoadError, 'package.json not found'
70
65
  end
71
66
 
72
- def build_development
73
- Dir.chdir absolute_path do
74
- pid = Process.spawn('npm run develop')
75
- Process.wait pid
76
- end
67
+ def check_for_npm
68
+ `npm -v`.strip
69
+ rescue Errno::ENOENT => e
70
+ warn "#{e.class}: #{e.message}"
71
+ warn 'Web app generation requires Node (https://nodejs.org).'
72
+ raise
77
73
  end
78
74
  end
79
75
  end
@@ -33,6 +33,7 @@ module Gamefic::Sdk::Tasks
33
33
 
34
34
  def define_task name, desc, &block
35
35
  return if Rake::Task.task_defined?(name)
36
+
36
37
  # @type [Rake::Task]
37
38
  task = Rake::Task.define_task(name, &block)
38
39
  task.add_description desc
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gamefic
2
4
  module Sdk
3
- VERSION = '2.5.0'
5
+ VERSION = '3.0.1'
4
6
  end
5
7
  end
@@ -1,14 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/<%= name %>/version"
4
+
1
5
  Gem::Specification.new do |spec|
2
- spec.name = '<%= name %>'
3
- spec.version = '1.0.0'
4
- spec.summary = 'A Gamefic library'
5
- spec.authors = ['Anomynous']
6
- spec.license = 'MIT'
7
- spec.files = Dir['lib/**/*.rb']
8
-
9
- spec.add_runtime_dependency 'gamefic', '~> 2.0'
10
- spec.add_runtime_dependency 'gamefic-standard', '~> 2.0'
11
-
12
- spec.add_development_dependency 'gamefic-sdk', '~> 2.0'
13
- spec.add_development_dependency 'rake', '~> 12.3'
6
+ spec.name = "<%= name %>"
7
+ spec.version = <%= camelcase(name) %>::VERSION
8
+ spec.authors = ["TODO: Author name(s)"]
9
+ spec.email = ["TODO: Author email(s)"]
10
+
11
+ spec.summary = "TODO: Write a short summary, because RubyGems requires one."
12
+ spec.description = "TODO: Write a longer description or delete this line."
13
+ spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
20
+ spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(__dir__) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ (File.expand_path(f) == __FILE__) ||
27
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
28
+ end
29
+ end
30
+ spec.bindir = "exe"
31
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_dependency 'gamefic', '~> 3.0'
35
+ spec.add_dependency 'gamefic-standard', '~> 3.0'
36
+
37
+ # For more information and examples about making a new gem, check out our
38
+ # guide at: https://bundler.io/guides/creating_gem.html
14
39
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module <%= camelcase(name) %>
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,10 @@
1
+ require 'gamefic'
2
+ require 'gamefic-standard'
3
+ require '<%= name %>/version'
4
+
5
+ module %<= camelcase(name) %>
6
+ extend Gamefic::Scriptable
7
+ include Gamefic::Standard
8
+
9
+ # Game code goes here
10
+ end
@@ -14,7 +14,7 @@ A Gamefic game project
14
14
 
15
15
  $ rake ruby:build
16
16
 
17
- The script will be saved in the `builds/ruby` directory.
17
+ The script will be saved in the `ruby/build` directory.
18
18
 
19
19
  ## Web-Based Games
20
20
 
@@ -31,13 +31,13 @@ To run the app in debug mode:
31
31
 
32
32
  $ rake web:run
33
33
 
34
- Open http://localhost:4342 in a browser.
34
+ Open http://localhost:9000 in a browser.
35
35
 
36
36
  ## Building a Web Game
37
37
 
38
38
  $ rake web:build
39
39
 
40
- The application will be saved in the `builds/web/production` directory.
40
+ The application will be saved in the `web/build` directory.
41
41
 
42
42
  ## More Information
43
43
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module <%= camelcase(name) %>
4
+ # The main plot.
5
+ #
6
+ class Plot < Gamefic::Plot
7
+ UUID = 'fe5d62a7-7036-45c0-b5cb-39c336bf1b5a'
8
+
9
+ include Gamefic::Standard
10
+
11
+ script do
12
+ introduction do |actor|
13
+ actor.tell "Hello, world!"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module <%= camelcase(name) %>
4
+ # The base subplot.
5
+ #
6
+ # Authors should extend this class to create subplots that the plot can
7
+ # branch.
8
+ #
9
+ class Subplot < Gamefic::Subplot
10
+ include Gamefic::Standard.no_scripts
11
+ end
12
+ end
@@ -1,9 +1,10 @@
1
- GAMEFIC_UUID = '<%= SecureRandom.uuid %>'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'gamefic'
3
4
  require 'gamefic-standard'
4
5
 
5
- Gamefic.script do
6
- introduction do |actor|
7
- actor.tell "Hello, world!"
8
- end
9
- end
6
+ require_relative '<%= name %>/plot'
7
+ require_relative '<%= name %>/subplot'
8
+
9
+ # The Gamefic SDK uses this constant to select the main Plot for game engines.
10
+ GAMEFIC_PLOT_CLASS = <%= camelcase(name) %>::Plot
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gamefic-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-11 00:00:00.000000000 Z
11
+ date: 2024-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gamefic
@@ -16,48 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.4'
19
+ version: '3.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.4'
26
+ version: '3.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: gamefic-standard
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.4'
33
+ version: '3.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.4'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: gamefic-tty
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.0'
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- version: 2.0.2
47
+ version: '3.0'
51
48
  type: :runtime
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
52
  - - "~>"
56
53
  - !ruby/object:Gem::Version
57
- version: '2.0'
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: 2.0.2
54
+ version: '3.0'
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: listen
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +80,20 @@ dependencies:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
82
  version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: puma
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6'
89
97
  - !ruby/object:Gem::Dependency
90
98
  name: sinatra
91
99
  requirement: !ruby/object:Gem::Requirement
@@ -142,20 +150,6 @@ dependencies:
142
150
  - - "~>"
143
151
  - !ruby/object:Gem::Version
144
152
  version: '3.3'
145
- - !ruby/object:Gem::Dependency
146
- name: puma
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '6'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '6'
159
153
  - !ruby/object:Gem::Dependency
160
154
  name: rake
161
155
  requirement: !ruby/object:Gem::Requirement
@@ -245,26 +239,15 @@ files:
245
239
  - scaffolds/library/Gemfile
246
240
  - scaffolds/library/README.md.gf.erb
247
241
  - scaffolds/library/__name__.gemspec.gf.erb
248
- - scaffolds/library/lib/__name__.rb
242
+ - scaffolds/library/lib/__name__.rb.gf.erb
243
+ - scaffolds/library/lib/__name__/version.rb.gf.erb
249
244
  - scaffolds/project/.gitignore
250
245
  - scaffolds/project/Gemfile
251
246
  - scaffolds/project/README.md.gf.erb
252
247
  - scaffolds/project/Rakefile
248
+ - scaffolds/project/__name__/plot.rb.gf.erb
249
+ - scaffolds/project/__name__/subplot.rb.gf.erb
253
250
  - scaffolds/project/main.rb.gf.erb
254
- - scaffolds/react/.babelrc
255
- - scaffolds/react/package.json.gf.erb
256
- - scaffolds/react/web/public/index.html.gf.erb
257
- - scaffolds/react/web/src/driver/development.js
258
- - scaffolds/react/web/src/driver/opal.rb
259
- - scaffolds/react/web/src/driver/production.js
260
- - scaffolds/react/web/src/index.js
261
- - scaffolds/react/web/src/scenes/Activity.jsx
262
- - scaffolds/react/web/src/scenes/Conclusion.jsx
263
- - scaffolds/react/web/src/scenes/MultipleChoice.jsx
264
- - scaffolds/react/web/src/scenes/Pause.jsx
265
- - scaffolds/react/web/src/scenes/index.js
266
- - scaffolds/react/web/src/style.css
267
- - scaffolds/react/webpack.config.js
268
251
  homepage: http://gamefic.com
269
252
  licenses:
270
253
  - MIT
@@ -1,5 +0,0 @@
1
- require 'gamefic-standard'
2
-
3
- Gamefic.script do
4
- # Game code goes here
5
- end
@@ -1,3 +0,0 @@
1
- {
2
- "presets" : ["@babel/preset-env", "@babel/preset-react"]
3
- }
@@ -1,34 +0,0 @@
1
- {
2
- "name": "<%= name %>",
3
- "version": "1.0.0",
4
- "description": "A Gamefic web app",
5
- "keywords": [],
6
- "author": "Anonymous",
7
- "license": "UNLICENSED",
8
- "private": true,
9
- "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1",
11
- "build": "webpack --mode production",
12
- "develop": "webpack --mode development"
13
- },
14
- "devDependencies": {
15
- "@babel/core": "^7.12.0",
16
- "babel-loader": "^8.2.2",
17
- "@babel/preset-env": "^7.12.10",
18
- "@babel/preset-react": "^7.12.10",
19
- "copy-webpack-plugin": "^7.0.0",
20
- "css-loader": "^5.0.1",
21
- "file-loader": "^6.2.0",
22
- "opal-webpack-bundler": "^0.0.1",
23
- "style-loader": "^0.23.1",
24
- "url-loader": "^4.1.1",
25
- "webpack": "^5.10.1",
26
- "webpack-cli": "^4.2.0"
27
- },
28
- "dependencies": {
29
- "gamefic-driver": "^0.2.1",
30
- "react": "^16.5.2",
31
- "react-dom": "^16.5.2",
32
- "react-gamefic": "^0.5.0"
33
- }
34
- }
@@ -1,11 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <title><%= name %></title>
6
- </head>
7
- <body>
8
- <div id="root" />
9
- <script src="bundle.js" type="text/javascript"></script>
10
- </body>
11
- </html>
@@ -1,4 +0,0 @@
1
- import { WebDriver } from 'gamefic-driver';
2
-
3
- const driver = new WebDriver('http://localhost:4342');
4
- export { driver };
@@ -1,7 +0,0 @@
1
- require 'opal'
2
- require 'gamefic'
3
- require 'main'
4
-
5
- $plot = Gamefic::Plot.new
6
- $character = $plot.get_player_character
7
- $plot.introduce $character
@@ -1,5 +0,0 @@
1
- import './opal.rb';
2
- import { OpalDriver } from 'gamefic-driver';
3
-
4
- const driver = new OpalDriver(Opal);
5
- export { driver };
@@ -1,28 +0,0 @@
1
- import React from 'react';
2
- import { render } from 'react-dom';
3
- import { Console, Terminal } from 'react-gamefic';
4
-
5
- import { driver } from 'driver';
6
-
7
- import { Activity, Pause, MultipleChoice, Conclusion } from './scenes';
8
- import 'react-gamefic/styles/ebook';
9
- import './style.css';
10
-
11
- const sceneComponents = {
12
- Activity: Activity,
13
- Pause: Pause,
14
- MultipleChoice: MultipleChoice,
15
- YesOrNo: MultipleChoice,
16
- Conclusion: Conclusion
17
- }
18
-
19
- render(
20
- <Console driver={driver}>
21
- <Terminal sceneComponents={sceneComponents} autoScroll={true} />
22
- </Console>,
23
- document.getElementById('root')
24
- );
25
-
26
- driver.start().then((state) => {
27
- driver.notify(state);
28
- });
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { ActivityScene, Output, CommandForm } from 'react-gamefic';
3
-
4
- export class Activity extends React.Component {
5
- render() {
6
- return (
7
- <ActivityScene>
8
- <Output {...this.props} transcribe={true} />
9
- <CommandForm prompt={this.props.state.prompt} />
10
- </ActivityScene>
11
- );
12
- }
13
- }
@@ -1,12 +0,0 @@
1
- import React from 'react';
2
- import { ConclusionScene, Output } from 'react-gamefic';
3
-
4
- export class Conclusion extends React.Component {
5
- render() {
6
- return (
7
- <ConclusionScene>
8
- <Output {...this.props} transcribe={true} />
9
- </ConclusionScene>
10
- );
11
- }
12
- }
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { MultipleChoiceScene, ChoiceList } from 'react-gamefic';
3
-
4
- export class MultipleChoice extends React.Component {
5
- render() {
6
- return (
7
- <MultipleChoiceScene>
8
- <Output {...this.props} transcribe={true} />,
9
- <ChoiceList options={this.props.state.options} prompt={this.props.state.prompt} />
10
- </MultipleChoiceScene>
11
- );
12
- }
13
- }
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import { PauseScene, Output, CommandLink } from 'react-gamefic';
3
-
4
- export class Pause extends React.Component {
5
- render() {
6
- return (
7
- <PauseScene>
8
- <Output {...this.props} transcribe={true} />
9
- <CommandLink command="">Continue</CommandLink>
10
- </PauseScene>
11
- );
12
- }
13
- }
@@ -1,11 +0,0 @@
1
- import { Activity } from './Activity.jsx';
2
- import { Pause } from './Pause.jsx';
3
- import { MultipleChoice } from './MultipleChoice.jsx';
4
- import { Conclusion } from './Conclusion.jsx';
5
-
6
- export {
7
- Activity,
8
- Pause,
9
- MultipleChoice,
10
- Conclusion
11
- }
@@ -1,3 +0,0 @@
1
- html {
2
- background-color: #EFEFEF;
3
- }
@@ -1,74 +0,0 @@
1
- const path = require('path');
2
- const CopyWebpackPlugin = require('copy-webpack-plugin');
3
-
4
- module.exports = (_env, argv) => {
5
- var config = {
6
- entry: path.resolve(__dirname, 'web', 'src', 'index.js'),
7
- output: {
8
- filename: 'bundle.js',
9
- path: path.resolve(__dirname, "builds", "web", argv.mode)
10
- },
11
- resolve: {
12
- alias: {
13
- driver: path.join(__dirname, 'web', 'src', 'driver', argv.mode)
14
- }
15
- },
16
- plugins: [
17
- new CopyWebpackPlugin({
18
- patterns: [
19
- {
20
- from: path.resolve(__dirname, 'web', 'public')
21
- }
22
- ]
23
- })
24
- ],
25
- module: {
26
- rules: [
27
- {
28
- test: /\.css$/,
29
- use: [
30
- 'style-loader',
31
- { loader: 'css-loader', options: { esModule: false } }
32
- ]
33
- },
34
- {
35
- test: /\.(png|jp(e*)g|svg)$/,
36
- use: [{
37
- loader: 'url-loader',
38
- options: {
39
- limit: 8000, // Convert images < 8kb to base64 strings
40
- name: 'images/[hash]-[name].[ext]'
41
- }
42
- }]
43
- },
44
- {
45
- test: /\.jsx?/,
46
- include: path.resolve(__dirname, 'web'),
47
- use: 'babel-loader'
48
- }
49
- ]
50
- }
51
- }
52
-
53
- if (argv.mode == 'production') {
54
- config.module.rules.push(
55
- {
56
- // opal-webpack-bundler will compile and include ruby files in the pack
57
- test: /\.rb$/,
58
- use: [
59
- {
60
- loader: 'opal-webpack-bundler',
61
- options: {
62
- useBundler: true,
63
- paths: [path.resolve(__dirname), path.resolve(__dirname, 'lib')],
64
- sourceMap: false,
65
- root: path.resolve(__dirname)
66
- }
67
- }
68
- ]
69
- }
70
- );
71
- }
72
-
73
- return config;
74
- };