mirror of
https://github.com/Oreolek/ink-instead.git
synced 2024-07-08 01:24:39 +03:00
merge, tests
This commit is contained in:
commit
9cbedd51c6
96
README.md
96
README.md
|
@ -1,10 +1,100 @@
|
|||
# pink
|
||||
An attempt to implement a subset of [ink](https://github.com/inkle/ink) in lua using [lpeg](http://www.inf.puc-rio.br/~roberto/lpeg)
|
||||
|
||||
## How to use this to run a game
|
||||
See the examples directory.
|
||||
_Ink is inkle's scripting language for writing interactive narrative, both for text-centric games as well as more graphical games that contain highly branching stories._
|
||||
|
||||
This is how to run the simple text-based example:
|
||||
## Currently supported
|
||||
|
||||
### Parser
|
||||
- Paragraphs
|
||||
- Comments
|
||||
- Choices
|
||||
- choice and output text
|
||||
- nested choices
|
||||
- Knots
|
||||
- Diverts
|
||||
- Glue
|
||||
- Include
|
||||
|
||||
### Runtime
|
||||
- state.visitCountAtPathString() - allows the runtime to check if the story went through a scpecific point
|
||||
|
||||
See [WritingWithInk](https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md) and [RunningYourInk](https://github.com/inkle/ink/blob/master/Documentation/RunningYourInk.md) for the description of the reference ink implementation.
|
||||
|
||||
## Used by
|
||||
pink is used by my small game https://github.com/premek/enjoy
|
||||
|
||||
Let me know if you want to use it too.
|
||||
|
||||
## Install dependencies
|
||||
|
||||
Install luarocks (Or see https://luarocks.org/#quick-start for instructions for other platforms):
|
||||
|
||||
sudo aptitude install luarocks
|
||||
|
||||
Install lpeg:
|
||||
|
||||
luarocks install --local lpeg
|
||||
|
||||
Get pink:
|
||||
|
||||
Clone this repo or download an archive from [releases](../../releases) page. You need just the `pink` subdirectory.
|
||||
|
||||
### Note on dependencies
|
||||
The pink **parser** depends on lpeg which can easily be instaled by luarocks (see above) but it may be difficult to distribute it with your game for each platform (it is a C library). Please consider compiling the .ink file into lua table, save it into a file and distribute just the compiled file with a lua table instead of compiling at runtime. (See: [#3](/../../issues/3))
|
||||
|
||||
Pink **runtime** is just a pure lua.
|
||||
|
||||
|
||||
## How to use this to run a game
|
||||
To use it in your project download the latest source or the latest [release](../../releases). You need just the [pink](../../tree/master/pink) directory.
|
||||
|
||||
### Example
|
||||
Given some .ink file like below, you can easily run it in your lua application using the pink library.
|
||||
|
||||
```ink
|
||||
=== back_in_london ===
|
||||
We arrived into London at 9.45pm exactly.
|
||||
* "There is not a moment to lose!"[] I declared. -> hurry_outside
|
||||
* "Monsieur, let us savour this moment!"[] I declared.
|
||||
My master clouted me firmly around the head and dragged me out of the door.
|
||||
-> dragged_outside
|
||||
|
||||
=== hurry_outside ===
|
||||
We hurried home to Savile Row -> as_fast_as_we_could
|
||||
|
||||
=== dragged_outside ===
|
||||
He insisted that we hurried home to Savile Row
|
||||
-> as_fast_as_we_could
|
||||
|
||||
=== as_fast_as_we_could ===
|
||||
<> as fast as we could.
|
||||
```
|
||||
|
||||
|
||||
```lua
|
||||
local pink = require('pink.pink')
|
||||
-- 1) Load story
|
||||
local story = pink.getStory('examples/game.ink')
|
||||
while true do
|
||||
-- 2) Game content, line by line
|
||||
while story.canContinue do
|
||||
print(story.continue())
|
||||
end
|
||||
-- 3) Display story.currentChoices list, allow player to choose one
|
||||
for i = 1, #story.currentChoices do
|
||||
print(i .. "> " .. story.currentChoices[i].text)
|
||||
end
|
||||
if #story.currentChoices == 0 then break end -- cannot continue and there are no choices
|
||||
local answer=io.read()
|
||||
print (story.currentChoices[tonumber(answer)].choiceText)
|
||||
story.chooseChoiceIndex(answer)
|
||||
end
|
||||
```
|
||||
|
||||
See the examples directory for a simple text based example and a LÖVE integration.
|
||||
|
||||
This is how to run the text-based example:
|
||||
|
||||
$ lua examples/game.lua
|
||||
|
||||
|
|
|
@ -1,41 +1,87 @@
|
|||
local folderOfThisFile = (...):match("(.-)[^%.]+$")
|
||||
local parser = require(folderOfThisFile .. 'parser')
|
||||
-- FIXME clean up
|
||||
|
||||
if not arg[1] and not (...) then error("Usage: `require` this file from a script or call `lua pink/pink.lua parse game.ink`") end
|
||||
local folderOfThisFile = arg[1] and string.sub(..., 1, string.len(arg[1]))==arg[1] and arg[0]:match("(.-)[^/\\]+$") or (...):match("(.-)[^%.]+$")
|
||||
local getParser = function () return require(folderOfThisFile .. 'parser') end
|
||||
local runtime = require(folderOfThisFile .. 'runtime')
|
||||
|
||||
|
||||
local function read(file)
|
||||
local function read(file) -- TODO should this be here or in client code? At lease allow to pass an ink content in a string
|
||||
if love and love.filesystem and love.filesystem.read then
|
||||
local content, size = love.filesystem.read(file)
|
||||
return content
|
||||
else
|
||||
local f = io.open(file, "rb")
|
||||
if not f then error('failed to open "'..file..'"') end
|
||||
local content = f:read("*all")
|
||||
f:close()
|
||||
return content
|
||||
end
|
||||
end
|
||||
|
||||
local function basename(str) return string.gsub(str, "(.*/)(.*)", "%2") end
|
||||
local function basedir(str) return string.gsub(str, "(.*)(/.*)", "%1") end
|
||||
|
||||
local api;
|
||||
|
||||
|
||||
api = {
|
||||
getStory = function (filename)
|
||||
local parse;
|
||||
parse = function(f)
|
||||
local parsed = {}
|
||||
for _,t in ipairs(parser:match(read(f))) do
|
||||
if t[2] and t[1]=='include' then
|
||||
for _,included in ipairs(parse(basedir(f)..'/'..t[2])) do
|
||||
table.insert(parsed, included)
|
||||
end
|
||||
else
|
||||
table.insert(parsed, t)
|
||||
end
|
||||
local parse;
|
||||
parse = function(f)
|
||||
local parsed = {}
|
||||
for _,t in ipairs(getParser():match(read(f))) do
|
||||
if t[2] and t[1]=='include' then
|
||||
for _,included in ipairs(parse(basedir(f)..'/'..t[2])) do
|
||||
table.insert(parsed, included)
|
||||
end
|
||||
return parsed
|
||||
else
|
||||
table.insert(parsed, t)
|
||||
end
|
||||
end
|
||||
return parsed
|
||||
end
|
||||
|
||||
return runtime(parse(filename))
|
||||
|
||||
|
||||
local api = {
|
||||
getStory = function (filename)
|
||||
local parsed
|
||||
if not pcall(function ()
|
||||
parsed = require (string.sub(filename, 1, -5))
|
||||
print('loaded precompiled story')
|
||||
end) then
|
||||
parsed = parse(filename)
|
||||
print('story compiled')
|
||||
end
|
||||
return runtime(parsed)
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
|
||||
local function dump ( t ) -- tables only
|
||||
local function sub_print_r(t)
|
||||
if (type(t)=="table") then
|
||||
local b = ""
|
||||
for pos,val in pairs(t) do
|
||||
if (type(val)=="table") then
|
||||
b = b .. "{"..sub_print_r(val).."},"
|
||||
elseif (type(val)=="string") then
|
||||
b = b .. '"'..string.gsub(val,'"', '\\"')..'",'
|
||||
else
|
||||
b = b .. tostring(val) .. ','
|
||||
end
|
||||
end
|
||||
return b
|
||||
else
|
||||
return tostring(t)
|
||||
end
|
||||
end
|
||||
return "-- This file was generated from an .ink file using the pink library - do not edit\nreturn {" .. sub_print_r(t) .. "}"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
if arg[1] == 'parse' and arg[2] then
|
||||
print(dump(parse(arg[2])))
|
||||
end
|
||||
|
||||
|
||||
return api
|
||||
|
|
10
test.lua
10
test.lua
|
@ -55,7 +55,15 @@ end
|
|||
|
||||
-- TODO test runtime more, test public pink API
|
||||
|
||||
|
||||
function testCLI()
|
||||
-- note the different suffixes
|
||||
os.execute("lua pink/pink.lua parse test/runtime/include.ink > tmp_test.lua")
|
||||
local story = pink.getStory('tmp_test.ink')
|
||||
luaunit.assertEquals(story.continue(), 'hello world')
|
||||
luaunit.assertEquals(story.continue(), 'hello again')
|
||||
luaunit.assertFalse(story.canContinue)
|
||||
os.remove('tmp_test.lua')
|
||||
end
|
||||
-----------------------------
|
||||
|
||||
function doTestS(ink, expected)
|
||||
|
|
Loading…
Reference in a new issue