Skip to main content

Placement

Based on game build 714014 | Last updated: 2026-02-27

Overview

This component provides utility functions for procedural placement of map nodes. It includes algorithms for generating positions on a grid (genRandomPositions), along circular patterns (genCircEdgePositions, genCircOffsetPositions), and logic for assigning these positions to nodes in a topology structure. It also exposes two high-level node placement strategies: PlaceNodesMode0 (deterministic traversal with offset-based conflict avoidance) and PlaceNodesRandom (shuffled position assignment using a provided position generator function). The module serves as a foundational utility for map generation and topology layout.

Usage example

local placement = require "map/placement"

-- Example: Place nodes using random offset positions
local topology = MyTopology()
local placedNodes = {} -- FIFO-style container (e.g., table with :push(), :pop())
local openEdges = {} -- FIFO-style container for edges to process

placement.random(topology, placedNodes, openEdges)

-- Example: Use a position generator function directly
local positions = placement.posfnCirc(8) -- generates 8 positions in spiral pattern

Dependencies & tags

Components used: None (this is a standalone utility module with no ECS component dependencies).
Tags: None identified.

Properties

PropertyTypeDefault ValueDescription
mode0functionPlaceNodesMode0High-level placement function using deterministic node-by-node traversal with offset-based positioning.
randomfunctionPlaceNodesRandomHigh-level placement function that assigns shuffled positions to nodes.
randpositonfunctionPositionNodesRandomApplies a given position generator function to a flat list of nodes.
posfnCircfunctiongenCircOffsetPositionsReturns a table of positions arranged in a spiral offset pattern.
posfnLinefunctiongenRandomPositionsReturns a table of positions arranged in a horizontal line with random Y offsets.
posfnCircEdgefunctiongenCircEdgePositionsReturns a table of positions arranged evenly on a unit circle perimeter.

Main functions

genRandomPositions(num)

  • Description: Generates num positions arranged in a horizontal line, where each x-coordinate spans from -floor(num/2) to floor(num/2) and y-coordinates are assigned randomly in [0, num]. The resulting list is shuffled in-place using Randomize.
  • Parameters: num (number) — Number of positions to generate.
  • Returns: table — Array of {x, y} position tables.
  • Error states: None.

genCircEdgePositions(num)

  • Description: Generates num positions evenly distributed along the perimeter of a unit circle (i.e., radius = 1). Positions are placed at uniform angular increments.
  • Parameters: num (number) — Number of positions to generate (must be > 0).
  • Returns: table — Array of {x, y} position tables.
  • Error states: Raises an assert error if num <= 0.

genCircOffsetPositions(num)

  • Description: Generates num positions arranged in a spiral offset pattern, using a parametric spiral formula (r = sqrt(s), θ = sqrt(s*512) where s = i/32). The resulting list is shuffled in-place.
  • Parameters: num (number) — Number of positions to generate (must be > 0).
  • Returns: table — Array of {x, y} position tables.
  • Error states: Raises an assert error if num <= 0.

PositionNodesRandom(nodes, center, positionFN)

  • Description: Assigns positions generated by positionFN to a flat list of nodes, centered around center. Modifies each node's position via node:SetPosition(...).
  • Parameters:
    • nodes (table) — Array-like list of node objects (supports pairs iteration).
    • center (table) — {x, y} offset to apply to all generated positions.
    • positionFN (function) — Function returning a table of positions (e.g., placement.posfnCirc).
  • Returns: nil.
  • Error states: Returns early if nodes is empty (count == 0).

PlaceNodesRandom(topology, placedNodes, openEdges)

  • Description: High-level node placement using spiral-offset positions generated by genCircOffsetPositions. Processes nodes from topology.root and populates placedNodes and openEdges (both expected to support :push()).
  • Parameters:
    • topology (table) — Map topology object containing root, which must have :GetNodes(recurse) method.
    • placedNodes (table) — FIFO-like container (must support :push()).
    • openEdges (table) — FIFO-like container (must support :push()).
  • Returns: nil.
  • Error states: None.

PlaceNodesMode0(topology, placedNodes, openEdges)

  • Description: High-level deterministic node placement that starts at topology.startNode, traverses edges using a stack (openEdges), and attempts to place each node at a grid-adjacent offset from the map center. Avoids duplicate positions by checking against placedNodes._et. Uses genMoveList to generate 36 possible directional offsets.
  • Parameters:
    • topology (table) — Map topology object containing startNode.
    • placedNodes (table) — FIFO-like container (must support :push() and access _et).
    • openEdges (table) — FIFO-like container (must support :push() and :pop()).
  • Returns: nil.
  • Error states: If a node cannot be placed after trying all offsets, prints error info to console and returns early.

Randomize(positions)

  • Description: Fisher-Yates shuffle implementation that randomizes positions in-place.
  • Parameters: positions (table) — Array to shuffle.
  • Returns: nil.
  • Error states: None.

genMoveList()

  • Description: Generates a shuffled list of 36 discrete movement offsets (step size 10 units) at 10-degree increments around a circle. Intended for use in PlaceNodesMode0.
  • Parameters: None.
  • Returns: table — Array of {x, y} offset tables.
  • Error states: None.

Events & listeners

None.