{"id":40026206,"url":"https://github.com/jackdoe/roblox-python-tower-defense","last_synced_at":"2026-01-19T04:02:25.090Z","repository":{"id":329341111,"uuid":"1117733001","full_name":"jackdoe/roblox-python-tower-defense","owner":"jackdoe","description":"save the core by writing python!","archived":false,"fork":false,"pushed_at":"2025-12-19T00:00:37.000Z","size":7974,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-21T22:42:19.524Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.roblox.com/games/92507403623309/Python-Tower-Defense","language":"Luau","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jackdoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-16T18:27:59.000Z","updated_at":"2025-12-19T00:00:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jackdoe/roblox-python-tower-defense","commit_stats":null,"previous_names":["jackdoe/roblox-python-tower-defense"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jackdoe/roblox-python-tower-defense","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdoe%2Froblox-python-tower-defense","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdoe%2Froblox-python-tower-defense/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdoe%2Froblox-python-tower-defense/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdoe%2Froblox-python-tower-defense/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jackdoe","download_url":"https://codeload.github.com/jackdoe/roblox-python-tower-defense/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jackdoe%2Froblox-python-tower-defense/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28561631,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T03:31:16.861Z","status":"ssl_error","status_checked_at":"2026-01-19T03:31:15.069Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-19T04:02:16.861Z","updated_at":"2026-01-19T04:02:25.070Z","avatar_url":"https://github.com/jackdoe.png","language":"Luau","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [PythonTD](https://www.roblox.com/games/92507403623309/Python-Tower-Defense)\n\n\u003e NB: 90% written by AI, nudged by jackdoe; run with rojo serve\nTower defense with programmable units.\n\n```python\nwhile True:\n    enemies = self.scan()\n    if len(enemies) \u003e 0:\n        self.set_target(nearest(enemies))\n        self.fire(BULLET)\n```\n![b](./screenshots/b.png)\n![a](./screenshots/a.png)\n\n## Ammo Types\n\nGundams use ammo from their magazine. Player weapons cost scrap (half gundam cost, half damage).\n\n### Gundam Weapons\n\n| Name    | Dmg | Ammo | Rate | Notes    |\n|---------|-----|------|------|----------|\n| BULLET  | 15  | 1    | 0.2s | Fast     |\n| ROCKET  | 80  | 4    | 1.0s | Splash, applies OILED |\n| LASER   | 40  | 2    | 0.1s | Burns    |\n| ICE     | 20  | 2    | 0.4s | 60% slow |\n| GRENADE | 60  | 5    | 1.5s | Splash   |\n\n### Player Weapons\n\n| Name    | Dmg | Scrap | Rate |\n|---------|-----|-------|------|\n| BULLET  | 7   | 1S    | 0.3s |\n| ROCKET  | 40  | 2S    | 1.0s |\n| LASER   | 20  | 1S    | 0.5s |\n| ICE     | 10  | 1S    | 0.4s |\n| GRENADE | 30  | 2S    | 1.5s |\n\nPlayer ROCKET applies OILED. Both ICE weapons freeze (60% slow).\n\n## Debuffs\n\n| Debuff  | Effect |\n|---------|--------|\n| SLOW    | Enemy moves at reduced speed. New slow replaces old. |\n| OILED   | Coated in oil for 5 seconds. Amplifies SHOCK damage 2x. |\n| BURNING | Takes 5 damage every 0.5s for 3s (30 total). From LASER. |\n| FROZEN  | Slowed by 50% or more. ROCKET shatters for 1.5x damage. |\n\n## Combos\n\nBots can SHOCK enemies to trigger powerful combos:\n\n| Combo | Effect |\n|-------|--------|\n| SHOCK + OILED   | 2x damage, explosion visual, clears oil |\n| SHOCK + BURNING | 1.5x damage, chains lightning to 3 nearby (30% dmg) |\n| SHOCK + SLOW    | (1 + slowAmount)x damage (60% slow = 1.6x) |\n| ROCKET + FROZEN | SHATTER: 1.5x damage, clears ice (needs 50%+ slow) |\n\nCombos stack **MULTIPLICATIVELY**! Order: cargo -\u003e oiled -\u003e burning -\u003e slow\n\n**Example:** 5 cargo + oiled + burning + 60% slow on 30 base shock:\n```\n30 × 7.6 (cargo) × 2 (oil) × 1.5 (burn) × 1.6 (slow) = 1094 damage!\n```\n\n- Chain lightning range: 15 units from target\n- Bot stuns for 2s after shocking (vulnerable!)\n\n## Types\n\n| Type     | Description |\n|----------|-------------|\n| Enemy    | A single enemy. Has hp, pos, is_boss, etc. |\n| [Enemy]  | A list of enemies. Use len() to count, [0] to get first. |\n| [x, z]   | A position. Two numbers: x (left/right), z (forward/back). |\n| AmmoType | One of: BULLET, ROCKET, LASER, ICE, GRENADE |\n| number   | A whole or decimal number like 10, 3.5, -20 |\n| bool     | True or False |\n\n## Objects: Self and Others\n\nEach unit (Gundam, Bot, Player) is an OBJECT with data and actions.\n\n### Self - Your Unit\n\n`self` refers to the unit running the code:\n\n```python\nself.pos                 # read your position\nself.carrying            # read how much scrap you have\nself.scan()              # perform a scan action\nself.fire(BULLET)        # perform a fire action\n```\n\n### Other Units - G1, G2, B1, B2, etc.\n\nYou can read data from other units on your team:\n\n```python\nB1.pos                   # where is Bot 1?\nB1.carrying              # how much scrap does Bot 1 have?\nG3.ammo                  # how much ammo does Gundam 3 have?\n```\n\n### Properties vs Methods\n\n**Properties** are data you READ (no parentheses):\n```python\nself.pos                 # [x, z] position\nself.carrying            # number of scrap\nself.ammo                # current ammo (Gundam)\nself.max_ammo            # max ammo capacity (Gundam)\nself.max_capacity        # max scrap capacity (Bot/Player)\nenemy.hp                 # enemy health\nenemy.is_boss            # True/False\n```\n\n**Methods** are actions you DO (use parentheses):\n```python\nself.scan()              # returns list of enemies\nself.fire(BULLET)        # shoots, returns True/False\nself.collect()           # picks up scrap\nself.teleport([0, 0])    # moves to position\nself.set_target(enemy)   # aims at enemy\n```\n\n### Example - Coordinated Attack\n\n```python\n# Bot checks if Gundam needs help\nif G1.ammo \u003c 50 and self.carrying \u003e 0:\n    self.say(\"G1 low on ammo!\")\n    self.teleport([0, 0])\n    self.deposit()\n```\n\n## Bot Abilities\n\n| Method/Property | Returns | Description |\n|-----------------|---------|-------------|\n| `self.collect()` | bool | Finds nearest scrap cluster and moves to collect it. |\n| `self.deposit()` | bool | Deposits carried scrap at core. Must be within 15 units. |\n| `self.shock(enemy)` | bool | Teleports to enemy and zaps for 30 base damage. Triggers combos! Damage scales with cargo: 30 × 1.5^cargo. Consumes HALF cargo (rounded up). |\n| `self.teleport([x, z])` | bool | Instantly moves to position. [0,0] is the core. |\n| `self.explode()` | bool | Sacrifices 10+ cargo for massive AOE. Bot is destroyed. |\n| `self.forward(n)` | bool | Walks forward n units in facing direction. |\n| `self.backward(n)` | bool | Walks backward n units. |\n| `self.left(degrees)` | bool | Rotates left. Default 90 degrees. |\n| `self.right(degrees)` | bool | Rotates right. Default 90 degrees. |\n| `self.scan()` | [Enemy] | Returns list of enemies within range 50. |\n| `self.say(\"message\")` | nothing | Shows a speech bubble above bot for 3 seconds. |\n| `self.carrying` | number | How much scrap bot is carrying. |\n| `self.max_capacity` | number | Maximum scrap bot can carry (10). |\n| `self.pos` | [x, z] | Current position relative to core. |\n| `self.hacker` | Player | Access your owner's player. Use `self.hacker.target()` etc. |\n\n**Shock damage examples:** 5 cargo = 228 dmg, 10 cargo = 1732 dmg!\n\n## Gundam Abilities\n\n| Method/Property | Returns | Description |\n|-----------------|---------|-------------|\n| `self.fire(AMMO)` | bool | **[BLOCKING]** Fires at current target. Waits for cooldown (scales with CPU). |\n| `self.scan()` | [Enemy] | Returns list of enemies within range. |\n| `self.set_target(enemy)` | nothing | Locks aim onto an enemy. Required before fire(). |\n| `self.target()` | Enemy/None | Returns currently targeted enemy, or None. |\n| `self.set_range(n)` | nothing | Sets base scan/attack range (10-60). Less range = more damage (40/range). Power upgrades extend effective range (+20% per power). |\n| `self.reload()` | number | Reloads ammo from scrap (2S per ammo). Returns amount reloaded. |\n| `self.ammo` | number | Current ammo in magazine. |\n| `self.max_ammo` | number | Maximum ammo capacity (300). |\n| `self.hacker` | Player | Access your owner's player. Use `self.hacker.target()` etc. |\n| `self.pos` | [x, z] | Current position relative to core. |\n\n## Player Abilities\n\n| Method/Property | Returns | Description |\n|-----------------|---------|-------------|\n| `self.fire(AMMO)` | bool | **[BLOCKING]** Fire at target. Costs scrap (see table). Waits for cooldown (scales with CPU). |\n| `self.scan()` | [Enemy] | Returns enemies within range 50. |\n| `self.set_target(enemy)` | nothing | Lock aim onto an enemy. |\n| `self.collect()` | bool | Picks up scrap within range 8. |\n| `self.teleport([x, z])` | bool | Instantly moves to position. |\n| `self.deposit()` | bool | Deposits scrap at core. Must be within 15 units. |\n| `self.drop(n)` | bool | Drops n scrap pieces (costs n×10 from wallet). Share with team! |\n| `self.explode()` | bool | AOE attack that consumes carried scrap. |\n| `self.carrying` | number | How much scrap player is carrying. |\n| `self.max_capacity` | number | Maximum scrap player can carry (10). |\n| `self.hacker` | Player | Returns yourself. Try `self.hacker.hacker.hacker.target()`! |\n| `self.pos` | [x, z] | Current position relative to core. |\n\n## Selectors\n\nThese pick ONE enemy from a list:\n\n| Function | Description |\n|----------|-------------|\n| `nearest([Enemy])` | Returns enemy closest to you. |\n| `furthest([Enemy])` | Returns enemy farthest from you. |\n| `weakest([Enemy])` | Returns enemy with lowest HP. |\n| `strongest([Enemy])` | Returns enemy with highest HP. |\n\n**Example:**\n```python\nenemies = self.scan()          # get list of enemies\ntarget = nearest(enemies)      # pick the closest one\nself.set_target(target)        # aim at it\n```\n\n## Enemy Properties\n\nWhen you scan, you get Enemy objects:\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `enemy.hp` | number | Current health |\n| `enemy.max_hp` | number | Maximum health |\n| `enemy.pos` | [x, z] | Position |\n| `enemy.is_boss` | bool | Is it a boss? |\n| `enemy.burning` | bool | Is it on fire? |\n| `enemy.frozen` | bool | Is it frozen (50%+ slow)? |\n| `enemy.slowed` | bool | Is it slowed at all? |\n| `enemy.oiled` | bool | Is it oiled? |\n\n## Global Variables\n\n| Variable | Description |\n|----------|-------------|\n| `CORE.hp` | Current core health |\n| `CORE.pos` | Core position [0, 0] |\n| `G1, G2, ... G10` | Access other gundams by ID |\n| `B1, B2, B3, ...` | Access bots by ID |\n\n## How Python Works\n\nYour code goes through 3 stages before running:\n\n1. **LEXER** - Reads your text and breaks it into tokens. `if x \u003e 5:` becomes: [IF] [x] [\u003e] [5] [:]. Tracks indentation for Python blocks.\n\n2. **COMPILER** - Converts tokens into bytecode instructions. `x = 5` becomes: LOAD_CONST 5, STORE_VAR x. Checks for errors like undefined variables.\n\n3. **VIRTUAL MACHINE (VM)** - Executes bytecode one instruction at a time. Uses a stack to compute values. Each CPU tick runs multiple instructions.\n\n## CPU, RAM, and Power\n\nEach unit has CPU speed (Hz), RAM (bytes), and Power multiplier.\n\n### CPU (Speed)\n\n- Base: 1 Hz\n- Each upgrade: +2 Hz\n- Cost: 200 scrap, then x2 per upgrade\n\n| Upgrade | Cost |\n|---------|------|\n| 1 Hz -\u003e 3 Hz | 200 scrap |\n| 3 Hz -\u003e 5 Hz | 400 scrap |\n| 5 Hz -\u003e 7 Hz | 800 scrap |\n\nHigher Hz = your program runs faster AND you fire faster!\n- Fire rate scales with CPU: `actualRate = baseRate / cpuHz`\n- At 5 Hz with BULLET (0.2s): fires every 0.04s instead of 0.2s!\n- Bot movement speed also scales: `baseSpeed + (cpuHz - 1) × 4`\n\n`fire()` is **BLOCKING** - your program waits for the cooldown.\n\n### RAM (Program Size)\n\n- Base: 32 bytes\n- Each upgrade: +32 bytes\n- Cost: 75 scrap, then x1.5 per upgrade\n\n| Upgrade | Cost |\n|---------|------|\n| 32B -\u003e 64B | 75 scrap |\n| 64B -\u003e 96B | 112 scrap |\n| 96B -\u003e 128B | 168 scrap |\n\nRAM limits your program size (bytecode instructions).\n- Simple loop = ~15 bytes\n- Full AI = ~60+ bytes\n\n### Power (Damage Multiplier)\n\n- Base: x1\n- Each upgrade: +1x\n- Cost: 200 scrap, then x2 per upgrade\n\n| Upgrade | Cost |\n|---------|------|\n| x1 -\u003e x2 | 200 scrap |\n| x2 -\u003e x3 | 400 scrap |\n| x3 -\u003e x4 | 800 scrap |\n\nPower multiplies all damage dealt by the unit. Also extends effective range (+20% per power level).\n\n## Economy\n\n- Starting scrap: 1000\n- Each player has their own scrap balance (not shared!)\n- Scrap drops from killed enemies\n- Your bots deposit scrap to YOUR balance\n- Use `self.drop(n)` to share scrap with teammates\n- Each scrap piece = 10 scrap currency\n- Damage scoreboard shows who's contributing!\n\n### Costs\n\n| Item | Cost |\n|------|------|\n| Gundam | 100 scrap base (×1.5 per gundam) |\n| Bot | 75 scrap base (×1.3 per bot, unlimited) |\n| CPU/RAM/Power upgrades | See tables above |\n| Player weapons | 1-2S per shot (see table) |\n\n## First Challenge\n\nThe default gundam program fires but **NEVER RELOADS!**\n\n```python\nwhile True:\n    enemies = self.scan()\n    if len(enemies) \u003e 0:\n        self.set_target(nearest(enemies))\n        self.fire(BULLET)\n```\n\nYour first task: add reload logic. But there's a catch...\n\n**Base RAM (32 bytes) is NOT enough for a full reload program!**\n\nYou must choose wisely:\n- Write minimal code that fits in 32 bytes\n- Or upgrade RAM first (costs scrap)\n- Or accept running dry and reloading manually\n\nThis is the machinist's dilemma: code efficiency vs upgrades.\n\n## Tips\n\n- ICE enemies before ROCKET for shatter bonus (freezes at 50%+ slow)\n- SHOCK oiled enemies for 2x damage + explosion\n- SHOCK burning enemies for 1.5x + chain lightning\n- Stack debuffs before SHOCK for multiplicative damage!\n- SHOCK teleports bot to target, then consumes all cargo\n- Bots can `teleport([0,0])` to instantly return to core\n- Lower range = more damage (40/range). Power boosts both damage and range.\n- Check `enemy.is_boss` to prioritize threats\n- Use `B1.carrying` to coordinate between units\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackdoe%2Froblox-python-tower-defense","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjackdoe%2Froblox-python-tower-defense","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjackdoe%2Froblox-python-tower-defense/lists"}