Scrapyard¶
A Lua-only mod: a charging scrap truck the announcer counts, a card that pulls cash from wrecks, a difficulty with its own rule, a run modifier, a weapon that fires a ring of scrap and shows its reach, a new trait for the game's drone rack, and a Safehouse line with code.
| Mod id | Kind | Files |
|---|---|---|
scrapyard |
Lua code | 3 |
Copy the whole folder into mods/ in the save folder to try it. Browse it on GitHub.
mod.json¶
{"id": "scrapyard", "title": "Scrapyard", "version": "1.0", "api": 1, "author": "Taxation Evasion",
"description": "A Lua-only mod: a charging scrap truck the announcer counts, a card that pulls cash from wrecks, a difficulty with its own rule, a run modifier, a weapon that fires a ring of scrap and shows its reach, a new trait for the game's drone rack, and a Safehouse line with code.",
"scripts": ["main.lua"]}
main.lua¶
-- Everything here goes through the `game` API (docs/modding/API.md).
-- An enemy: a gang car that charges when close and bursts when destroyed.
game.add('enemies', {
id = 'scrapyard.truck', base = 'gang', label = 'SCRAP TRUCK',
sprite = 'player_van', tint = {150, 110, 70},
hp = 40, speed = 300, gold = 60,
spawn = {heat = 3, every = 25, max_alive = 2},
behavior = 'scrapyard.truck',
})
game.enemy('scrapyard.truck', {
think = function(s, e, dt)
if game.distance(e, s.player) < 140 then
game.drive(s, e, s.player.x, s.player.y, 480, dt)
return true
end
end,
death = function(s, e)
game.blast(s, e.x, e.y, 48, 200)
game.sound(s, 'scrapyard.clank', 0.5) -- sfx/clank.wav
-- The announcer keeps the tally, with the live number in its line.
s.scrapyard_wrecks = (s.scrapyard_wrecks or 0) + 1
game.say(s, 'scrapyard.truck_down', {'Scrap truck down.', s.scrapyard_wrecks .. ' wrecked this run.'})
end,
})
game.add('announcer', {
id = 'scrapyard.truck_down', lines = {'Scrap truck down.', 'Keep them coming.'},
priority = 2, cooldown = 20,
})
-- A card: every wreck pays a little cash per rank.
game.effect('scrapyard.salvage', {
kills = function(s, count, rank) game.cash(s, 5 * count * rank) end,
})
game.add('cards', {
id = 'scrapyard.salvage', name = 'SALVAGE', tier = 'part', max = 3, icon = 18,
description = 'Each wreck pays $5 per rank.', effect = 'scrapyard.salvage',
})
-- A difficulty with a rule only code can express: NOS drains slowly.
game.effect('scrapyard.leaky_tank', {
tick = function(s, dt) game.nos(s, -0.02 * dt) end,
})
game.add('difficulties', {
id = 'scrapyard.leaky', numeral = 'L', name = 'LEAKY TANK', short = 'LEAKY NOS',
rule = 'YOUR NOS TANK SLOWLY DRAINS', payout = 1.5,
crowd = 1.25, effect = 'scrapyard.leaky_tank',
})
-- A run modifier with code: every wreck mends half a heart.
game.effect('scrapyard.scrap_repairs', {
kills = function(s, count) game.heal(s, 0.5 * count) end,
})
game.add('modifiers', {
id = 'scrapyard.scrap_repairs', name = 'SCRAP REPAIRS', description = 'EVERY WRECK MENDS HALF A HEART',
payout = 0.75, effect = 'scrapyard.scrap_repairs',
})
-- A weapon with a pattern of its own: a ring of scrap whenever an enemy is
-- near. Its gear card and numbers are content; only the firing is code.
game.weapon('scrapyard.ring', {
fire = function(s, w, dt)
w.state.wait = (w.state.wait or 0) - dt
if w.state.wait > 0 or not game.target(s, w.stats.range) then return end
w.state.wait = w.stats.interval
for i = 1, w.stats.rounds do
game.fire(s, w, i / w.stats.rounds * 2 * math.pi)
end
end,
-- Scrap hits undamaged cars twice as hard.
hit = function(s, e, damage)
if e.hp >= (e.max_hp or e.hp) then return damage * 2 end
end,
-- A faint ring shows the cannon's reach while it is loaded.
draw = function(s, w, d)
if (w.state.wait or 0) <= 0 then d.ring(s.player.x, s.player.y, w.stats.range, {170, 140, 100}, 0.35) end
end,
})
game.add('cards', {
id = 'scrapyard.scrap_cannon', name = 'SCRAP CANNON', tier = 'gear', branch = 'scrap', max = 1, icon = 12,
description = 'Throws a ring of scrap when an enemy is near.',
})
game.add('weapons', {
id = 'scrapyard.scrap_cannon', pattern = 'scrapyard.ring',
range = 90, interval = 1.5, damage = 2, rounds = 8, speed = 240, color = {170, 140, 100},
})
-- A trait for one of the game's own weapons: with SCRAP COILS, every fifth
-- zap from the drone rack hits three times as hard. The card is an upgrade
-- on the base drone row; the rack keeps all its other cards.
game.trait('drone', 'scrapyard.overcharge', {
hit = function(s, e, damage, w)
w.state.zaps = (w.state.zaps or 0) + 1
if w.state.zaps % 5 == 0 then return damage * 3 end
end,
})
game.add('cards', {
id = 'scrapyard.scrap_coils', name = 'SCRAP COILS', tier = 'part', max = 1, icon = 12, requires = 'drone',
description = 'Every fifth drone zap hits three times as hard.',
})
game.change('weapons', 'drone', {upgrades = {['scrapyard.scrap_coils'] = {['scrapyard.overcharge'] = true}}})
-- A Safehouse line with code: bought between runs, it runs in every run
-- with its level as the rank. Each wreck refills 2% of the NOS tank a level.
game.effect('scrapyard.junk_magnet', {
kills = function(s, count, rank) game.nos(s, 0.02 * rank * count) end,
})
game.add('safehouse', {
id = 'scrapyard.junk_magnet', label = 'JUNK MAGNET', line = 'EACH WRECK REFILLS 2% NOS PER LEVEL',
max = 5, base = 600, effect = 'scrapyard.junk_magnet',
})