FAQ  •  Register  •  Login

minefield.lua

<<

kaen

User avatar

Posts: 209

Joined: Thu Jun 14, 2012 11:54 am

Post Thu Mar 21, 2013 5:38 am

minefield.lua

Here's a usage guide for minefield.lua, which was a central component to my Bebop and Ricochet submissions to the Wild West design contest. It periodically spawns mines in specified zones, allowing you to create minefield(s) with respawning and randomly placed mines.

The levelgen was meant to be used without needing to edit it at all. In fact many different levels can use the same script file in different ways by simply changing the arguments you pass to it. When you type the name of the levelgen into the editor, you can pass it "arguments" (i.e. options) by typing things after the name. The general form is:

  Code:
minefield.lua [time] [min_mines] [max_mines] [zones]


"time" is in milliseconds (thousandths of a second), and is the time between each spawned wave of mines. min_mines and max_mines are the inclusive bounds for the number of mines to spawn, and zones is a lua table of zone ids. If you wanted to spawn 1 to 3 mines every ten seconds in zones 1, 2, and 3, you would type:

  Code:
minefield.lua 10000 1 3 {1,2,3}


These are also the default values, so the above is the same as simply typing:

  Code:
minefield.lua


Finally, the first three arguments can be mathematical expressions (or actually any valid lua) that includes a variable "t" which represents the number of milliseconds since the level started. For example, to lay a number of mines (every second) between 0 and the number of seconds which has passed since the level started, you could use:

  Code:
minefield.lua 1000 0 t/1000


Bugs:
  • Bitfighter uses spaces to parse arguments to levelgens, so you must not put spaces into your expressions or zone lists. Cram it all together, but put a single space between each argument
  • It uses the rectangular extents of zones, so your 16-sided curvilinear minefield will actually behave like the smallest axis-aligned rectangle which contains it. (tl;dr: use rectangular zones)

minefield.lua:
  Code:

-- minefield.lua [interval] [min_mines] [max_mines] [mine_zones]
-- interval - time in milliseconds between mine spawns
-- min/max_mines - inclusive bounds for the number of mines to spawn
-- mine_zones - a table (array) of ids of zones which are minefields
--
-- interval and min/max mines are processed using 'evaluate' below for each
-- invocation of mineEvent. This allows you to express these values in terms of
-- 't', which is the number of milliseconds since the level was loaded. For
-- instance, "minefield.lua 1000 1 1+t/1000" will spawn upto as many mines as
-- the number of full seconds since the level was loaded

START_TIME = getMachineTime()

-- find the value of the string at time t
function evaluate(str)
    return loadstring("t = " .. (getMachineTime() - START_TIME) .. " ; return " .. str)()
end

-- pick a random point within extents
function randomPoint(extents)
    return point.new(math.random(extents.minX, extents.maxX), math.random(extents.minY, extents.maxY))
end

-- return a well-labeled table of extents
function getExtents(zone)
    minX, minY, maxX, maxY = math.huge, math.huge, -math.huge, -math.huge
    for index, p in pairs(zone:getGeom()) do
        minX = math.min(minX, p.x)
        minY = math.min(minY, p.y)
        maxX = math.max(maxX, p.x)
        maxY = math.max(maxY, p.y)
    end
    extents = {}
    extents.minX = minX
    extents.maxX = maxX
    extents.minY = minY
    extents.maxY = maxY
    return extents
end

-- lay some mines in the minefields
function layMines()
    -- for each minefield
    for index, id in pairs(MINE_FIELDS) do
        -- lay between min and max mines
        for i = 1, math.random(MINE_MIN, evaluate(MINE_MAX)) do
            mineField = levelgen:findObjectById(id)
            -- only if the minefield exists
            if mineField ~= nil then
                p = randomPoint(getExtents(mineField))
                mine = Mine.new(p)
                levelgen:addItem(mine)
            end
        end
    end
end

function mineEvent()
    layMines()
    Timer:scheduleOnce(mineEvent, math.max(100, evaluate(MINE_INTERVAL)))
end

MINE_INTERVAL = 10000
MINE_MIN = 1
MINE_MAX = 3
MINE_FIELDS = {1, 2, 3}

function main()
    MINE_INTERVAL = arg[1] or MINE_INTERVAL
    MINE_MIN = arg[2] or MINE_MIN
    MINE_MAX = arg[3] or MINE_MAX
    MINE_FIELDS = loadstring("return " .. (arg[4] or "false"))() or MINE_FIELDS

    mineEvent()
end
 
bobdaduck wrote:Next, the moon!

└────────┘
⎈⎈⎈⎈
┌────────┐
<<

sky_lark

User avatar

Posts: 2053

Joined: Wed Mar 10, 2010 6:00 pm

Post Thu Mar 21, 2013 8:20 am

Re: minefield.lua

Cool!
Follow Bitfighter! FacebookTwitterDiscord
<<

raptor

Posts: 1046

Joined: Mon Oct 11, 2010 9:03 pm

Post Thu Mar 21, 2013 10:07 am

Re: minefield.lua

Wow great!

(I had no idea you could pass arguments like that..)
<<

watusimoto

Site Admin

Posts: 1558

Joined: Tue Feb 23, 2010 7:07 pm

Location: Quartz's mom's house

Post Thu Mar 21, 2013 11:55 am

Re: minefield.lua

Would a regular minefield object that could be added via the editor (with no need for a script) be a good thing to add?
<<

kaen

User avatar

Posts: 209

Joined: Thu Jun 14, 2012 11:54 am

Post Thu Mar 21, 2013 12:20 pm

Re: minefield.lua

I believe so. This script has some unfixable flaws:

  • It's more complicated than a level line
  • Its structure prevents it from being used with other levelgens without surgery
  • If you remove the safeguard you can semi-forkbomb (fiberbomb?) the lua interpreter (a separate, larger issue which I stumbled over while writing it)

Even the sugary "t" interpolation could be emulated by an interested scripter with API which spawns currently expose. Maybe you guys can figure out how to select a random point on an arbitrarily shaped polygon, too :)
bobdaduck wrote:Next, the moon!

└────────┘
⎈⎈⎈⎈
┌────────┐
<<

Lamp

User avatar

Posts: 426

Joined: Fri Jan 11, 2013 3:07 pm

Post Fri Mar 22, 2013 8:09 pm

Re: minefield.lua

For some reason the mines only spawn at the top of the zone, and also sometimes even the corner!

http://youtu.be/tlw7AxJPeLk
Image
<<

Lamp

User avatar

Posts: 426

Joined: Fri Jan 11, 2013 3:07 pm

Post Fri Mar 22, 2013 8:10 pm

Re: minefield.lua

also it's suppost to be minefield.levelgen, not minefield.lua.

no wonder it didnt work.
Image
<<

kaen

User avatar

Posts: 209

Joined: Thu Jun 14, 2012 11:54 am

Post Sat Mar 23, 2013 7:01 am

Re: minefield.lua

You could name it "anythingyouwant.madeupextension" if you wanted. You just have to retype it correctly in the editor.

However, you did find a bug. The minefields only work properly in one quadrant of the grid. I'll fix it tonight.
bobdaduck wrote:Next, the moon!

└────────┘
⎈⎈⎈⎈
┌────────┐

Return to General Map/Server

Who is online

Users browsing this forum: No registered users and 2 guests

cron