Created
October 8, 2014 00:13
-
-
Save Johnicholas/a43fafdeb3b632d854a5 to your computer and use it in GitHub Desktop.
Transliteration perl->lua of thgie's implementation of Doran and Parberry's procedural quest system
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- procedural quest generation | |
math.randomseed(os.time()) | |
local DEPTH = 3 | |
actions = { | |
goto = { | |
{ description = 'Just wander around and look', | |
sequence = { '>explore' } | |
}, | |
{ description = 'Find out where to go and go there', | |
sequence = { 'learn', '>goto' } | |
} | |
}, | |
learn = { | |
{ description = 'Go someplace, get something, and read what is written on it', | |
sequence = { 'goto', 'get', '>read' } | |
} | |
}, | |
get = { | |
{ description = 'Steal it from somebody', sequence = { 'steal' } }, | |
{ description = 'Go someplace and pick something up that is lying around there', | |
sequence = { 'goto', '>gather' } | |
} | |
}, | |
steal = { | |
{ description = 'Go someplace, sneak up on somebody, and take something', | |
sequence = { 'goto', '>stealth', '>take' } | |
}, | |
{ description = 'Go someplace, kill somebody and take something', | |
sequence = { 'goto', 'kill', '>take' } | |
} | |
}, | |
spy = { | |
{ description = 'Go someplace, spy on somebody, return and report', | |
sequence = { 'goto', '>spy', 'goto', '>report' } | |
}, | |
}, | |
capture = { | |
{ description = 'Get something, go someplace and use it to capture somebody', | |
sequence = { 'get', 'goto', '>capture' } | |
} | |
}, | |
kill = { | |
{ description = 'Go someplace and kill somebody', | |
sequence = { 'goto', '>kill' } | |
} | |
}, | |
} | |
motivations = { | |
knowledge = { | |
{ description = 'Deliver item for study', | |
sequence = { 'get', 'goto', '>give' } | |
}, | |
{ description = 'Spy', sequence = { 'spy' } }, | |
{ description = 'Interview NPC', | |
sequence = { 'goto', '>listen', 'goto', '>report' } | |
}, | |
{ description = 'Use an item in the field', | |
sequence = { 'get', 'goto', '>use', 'goto', '>give' } | |
} | |
}, | |
comfort = { | |
{ description = 'Obtain luxuries', | |
sequence = { 'get', 'goto', '>give' } | |
}, | |
{ description = 'Kill pests', | |
sequence = { 'goto', '>damage', 'goto', '>report' } | |
}, | |
}, | |
reputation = { | |
{ description = 'Obtain rare items', | |
sequence = { 'get', 'goto', '>give' } | |
}, | |
{ description = 'Kill enemies', | |
sequence = { 'goto', 'kill', 'goto', '>report' } | |
}, | |
{ description = 'Visit a dangerous place', | |
sequence = { 'goto', 'goto', '>report' } | |
} | |
}, | |
serenity = { | |
{ description = 'Revenge, justice', | |
sequence = { 'goto', '>damage' } | |
}, | |
{ description = 'Capture Criminal(1)', | |
sequence = { 'get', 'goto', '>use', 'goto', '>give' } | |
}, | |
{ description = 'Capture Criminal(2)', | |
sequence = { 'get', 'goto', '>use', '>capture', 'goto', '>give' } | |
}, | |
{ description = 'Check on NPC(1)', | |
sequence = { 'goto', '>take', 'goto', '>give' } | |
}, | |
{ description = 'Recover lost/stolen item', | |
sequence = { 'get', 'goto', '>give' } | |
}, | |
{ description = 'Rescue captured NPC', | |
sequence = { 'goto', '>damage', '>escort', 'goto', '>report' } | |
} | |
}, | |
protection = { | |
{ description = 'Attack threatening entities', | |
sequence = { 'goto', '>damage', 'goto', '>report' } | |
}, | |
{ description = 'Treat or repair (1)', | |
sequence = { 'get', 'goto', '>use' } | |
}, | |
{ description = 'Treat or repair (2)', | |
sequence = { 'goto', '>repair' } | |
}, | |
{ description = 'Create Diversion (1)', | |
sequence = { 'get', 'goto', '>use' } | |
}, | |
{ description = 'Create Diversion (2)', | |
sequence = { 'goto', '>damage' } | |
}, | |
{ description = 'Assemble fortification', | |
sequence = { 'goto', 'repair' } | |
}, | |
{ description = 'Guard entity', | |
sequence = { 'goto', '>defend' } | |
} | |
}, | |
conquest = { | |
{ description = 'Attack enemy', sequence = { 'goto', '>damage' } }, | |
{ description = 'Steal stuff', | |
sequence = { 'goto', 'steal', 'goto', '>give' } | |
} | |
}, | |
wealth = { | |
{ description = 'Gather raw materials', sequence = { 'goto', 'get' } }, | |
{ description = 'Steal valuables for resale', | |
sequence = { 'goto', 'steal' } }, | |
{ description = 'Make valuables for resale', | |
sequence = { '>repair' } | |
} | |
}, | |
ability = { | |
{ description = 'Assemble tool for new skill', | |
sequence = { '>repair', '>use' } | |
}, | |
{ description = 'Obtain training materials', | |
sequence = { '>get', '>use' } | |
}, | |
{ description = 'Use existing tools', | |
sequence = { '>use' } | |
}, | |
{ description = 'Practice combat', | |
sequence = { '>damage' } | |
}, | |
{ description = 'Practice skill', | |
sequence = { '>use' } | |
}, | |
{ description = 'Research a skill(1)', | |
sequence = { 'get', '>use' } | |
}, | |
{ description = 'Research a skill(1)', | |
sequence = { 'get', '>experiment' } | |
} | |
}, | |
equipment = { | |
{ description = 'Assemble', sequence = { '>repair' } }, | |
{ description = 'Deliver supplies', | |
sequence = { 'get', 'goto', '>give' } | |
}, | |
{ description = 'Steal supplies', | |
sequence = { 'steal' } | |
}, | |
{ description = 'Trade for supplies', | |
sequence = { 'goto', '>exchange' } | |
} | |
} | |
} | |
function randomly_choose(array) | |
return array[math.random(#array)] | |
end | |
local generated_subs = {} | |
local current_depth = 0 | |
for action, options in pairs(actions) do | |
generated_subs[action] = function () | |
local choice = options[math.random(#options)] | |
local description = choice.description | |
local sequence = choice.sequence | |
current_depth = current_depth + 1 | |
local padding = string.rep(' ', current_depth) | |
print(padding .. '[' .. description .. ']') | |
for _, step in ipairs(sequence) do | |
print(padding .. step) | |
if step:sub(1, 1) ~= '>' and | |
current_depth + 1 <= DEPTH | |
then | |
assert(generated_subs[step], 'could not find: ' .. step) | |
generated_subs[step]() | |
end | |
end | |
current_depth = current_depth - 1 | |
end | |
end | |
local mlist = {} | |
for motivation, _ in pairs(motivations) do | |
table.insert(mlist, motivation) | |
end | |
local motivation = mlist[math.random(#mlist)] | |
local options = motivations[motivation] | |
choice = options[math.random(#options)] | |
print('generating a quest for: ' .. motivation .. ': ' .. choice.description) | |
for _, step in ipairs(choice.sequence) do | |
print(step) | |
if step:sub(1, 1) ~= '>' then | |
generated_subs[step]() | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment