Coding Adventure with Kaggle and Lux AI
Based on sentdex's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Start with the provided Lux AI “simple” bot, run local matches, and use replay inspection as the primary debugging loop.
Briefing
Lux AI’s Kaggle 1v1 competition rewards the simplest end condition: finish with more city tiles than the opponent. The core takeaway from this coding run is that a bot can jump from “bottom-tier” to “competitive” with incremental, test-driven improvements—starting from a minimal working submission, then adding just enough strategy to reliably expand city area before nightfall punishes low fuel.
The walkthrough begins by setting up Lux AI locally via Node.js and installing the competition package, then using the provided Python “simple” bot as a baseline. Running “simple vs simple” on a 24x24 map generates replay files that can be inspected through the Lux viewer. That replay-driven loop becomes the development workflow: make a change, run a match, inspect behavior, and iterate—because stepping through full-speed games with logging alone quickly becomes painful.
Early on, the author frames the competitive reality: many teams sit at a single city tile, so building just one additional tile can move a bot from the bottom into a much higher percentile. But strategy code tends to sprawl, so the next move is structural cleanup—extracting repeated logic into helper functions like “get resource tiles,” “get close resource,” and “get close city.” The goal isn’t fewer lines; it’s isolating strategy decisions from mechanics so future expansions don’t turn the agent into an unmaintainable tangle.
With the bot cleaned up, the strategy shifts to expansion. A city tile requires 100 resources, and the bot’s workers carry 100 each, so the author adds logic to build a second city tile adjacent to an existing one. To do that correctly, the code must interpret Lux’s data model: “cities” are collections of “city tiles,” and adjacent tiles belong to the same city. The bot also logs and then derives city tile lists from the city objects, ensuring it can decide when it has enough tiles to stop building.
A major practical bug appears when workers naively navigate onto city tiles: Lux deposits cargo immediately, so a worker can repeatedly cross a city tile, dump resources, then return to refill—stalling the intended build. The fix is to improve movement so workers avoid running over city tiles while heading to a build location. Later, as the bot expands, it adds more workers and more city tiles using global dictionaries that track which worker is assigned to which city tile and which resource tile. It also addresses collisions and “stuck” units by tracking recent positions and applying a random cardinal move when a worker hasn’t changed coordinates over multiple steps.
Finally, the author introduces a simple evaluation harness for hyperparameter tuning: log the number of city tiles at the end of each game (especially watching for runs that end with zero city tiles, which often indicate the city died during night). A small change—searching for build locations within a larger radius—produces a noticeable improvement in average city tiles. The resulting bot scores 656, with clear room to improve via better navigation, smarter fuel management as night approaches, and more robust collision avoidance. The submission process is straightforward: compress to tar.gz and upload to Kaggle, then compare against other teams after matches begin.
Cornell Notes
The competition’s win condition is straightforward: end the game with more city tiles than the opponent. Starting from Lux AI’s provided “simple” bot, the author iteratively adds city expansion while keeping the agent maintainable by extracting repeated mechanics into helper functions. The bot then learns the game’s data model (cities are collections of city tiles) and uses worker cargo rules (100 resources per city tile) to build additional tiles adjacent to existing ones. Practical issues—workers depositing cargo by stepping on city tiles, units colliding or getting stuck, and cities dying before night—are handled with improved movement logic, position tracking, and fuel-based decisions about when to expand. Hyperparameters are tuned by logging final city-tile counts and comparing outcomes across runs.
Why does building just one extra city tile matter so much early in the competition?
What’s the key data-model detail needed to manage expansion correctly?
Why do naive navigation choices prevent city expansion even when the build logic is correct?
How does the bot scale from “one city tile” to “multiple city tiles” without losing control of assignments?
What mechanism helps when units collide or get stuck?
How does the author tune hyperparameters without building a complex analytics pipeline?
Review Questions
- What specific Lux mechanic makes workers deposit cargo when they step on city tiles, and how does that interfere with building adjacent tiles?
- How does tracking recent unit positions help distinguish a stuck unit from normal movement, and what action is taken afterward?
- Why does deriving city tiles from player.cities matter for both expansion decisions and worker assignment?
Key Points
- 1
Start with the provided Lux AI “simple” bot, run local matches, and use replay inspection as the primary debugging loop.
- 2
Keep agent logic maintainable by extracting repeated mechanics (resource discovery, closest-tile selection) into helper functions.
- 3
Build additional city tiles by leveraging the 100-resources-per-city-tile rule and by correctly deriving city tiles from Lux’s city data model.
- 4
Avoid sending workers across existing city tiles while they’re trying to reach a build location, since immediate cargo deposition can create loops that prevent building.
- 5
Scale expansion by tracking worker-to-city-tile and worker-to-resource assignments using global dictionaries, then decide when to expand based on worker-to-city-tile ratios and fuel needs.
- 6
Handle collisions and stuck units by tracking recent positions and applying a corrective move when a unit hasn’t changed coordinates over multiple steps.
- 7
Tune strategy parameters by logging final city-tile counts and comparing outcomes across runs, especially watching for games that end with zero city tiles.