Skip to content

Instantly share code, notes, and snippets.

@Johnicholas
Created October 8, 2014 00:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Johnicholas/a43fafdeb3b632d854a5 to your computer and use it in GitHub Desktop.
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
-- 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