spawnpoint-studio 0.3.3__tar.gz → 0.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. {spawnpoint_studio-0.3.3/compiler/spawnpoint_studio.egg-info → spawnpoint_studio-0.3.5}/PKG-INFO +60 -18
  2. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/README.md +59 -17
  3. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/analyze.py +31 -4
  4. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/build.py +3 -1
  5. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cli.py +29 -2
  6. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/demo.py +9 -5
  7. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/demo_touch.js +1 -1
  8. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/gif.py +24 -5
  9. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/graph.py +22 -0
  10. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/llm_server.py +1 -1
  11. spawnpoint_studio-0.3.5/compiler/spawnpoint/logo.py +167 -0
  12. spawnpoint_studio-0.3.5/compiler/spawnpoint/music.py +117 -0
  13. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/cartoon.py +4 -0
  14. spawnpoint_studio-0.3.5/compiler/spawnpoint/sprites/farm.py +1468 -0
  15. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/gallery.py +12 -0
  16. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/generate.py +15 -1
  17. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/resolve.py +4 -2
  18. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/assemble.py +213 -35
  19. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/brief.py +9 -0
  20. spawnpoint_studio-0.3.5/compiler/spawnpoint/studio/farmgen.py +353 -0
  21. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/levelgen.py +0 -39
  22. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/prompts.py +11 -1
  23. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/webcheck.py +22 -6
  24. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5/compiler/spawnpoint_studio.egg-info}/PKG-INFO +60 -18
  25. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/SOURCES.txt +18 -0
  26. spawnpoint_studio-0.3.5/compiler/tests/test_farm.py +224 -0
  27. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_genres.py +3 -2
  28. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_sprites.py +2 -1
  29. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_studio.py +1 -1
  30. spawnpoint_studio-0.3.5/examples/sunny_farm.json +1043 -0
  31. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/animator_component.gd +15 -1
  32. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_animal_component.gd +196 -0
  33. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_days_component.gd +186 -0
  34. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/farm_plot_component.gd +111 -5
  35. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_save_component.gd +193 -0
  36. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farmer_component.gd +445 -0
  37. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/fishing_spot_component.gd +103 -0
  38. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/game_menu_component.gd +157 -0
  39. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/gatherable_component.gd +70 -0
  40. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/market_component.gd +4 -0
  41. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/shop_component.gd +109 -0
  42. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/sleep_spot_component.gd +27 -0
  43. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/sprinkler_component.gd +58 -0
  44. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/tool_bench_component.gd +73 -0
  45. spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/warp_component.gd +76 -0
  46. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/manifest.json +749 -23
  47. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/game_state.gd +4 -0
  48. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/sfx.gd +30 -0
  49. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/build.gd +13 -0
  50. spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/overview.gd +44 -0
  51. spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/overview.tscn +6 -0
  52. spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/record.gd +435 -0
  53. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/pyproject.toml +1 -1
  54. spawnpoint_studio-0.3.3/examples/sunny_farm.json +0 -224
  55. spawnpoint_studio-0.3.3/godot/addons/spawn_point/components/farmer_component.gd +0 -158
  56. spawnpoint_studio-0.3.3/godot/addons/spawn_point/tools/record.gd +0 -233
  57. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/LICENSE +0 -0
  58. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/MANIFEST.in +0 -0
  59. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/__init__.py +0 -0
  60. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/__init__.py +0 -0
  61. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/server.py +0 -0
  62. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/app.css +0 -0
  63. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/app.js +0 -0
  64. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/index.html +0 -0
  65. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/diagnostics.py +0 -0
  66. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/expr.py +0 -0
  67. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/godot.py +0 -0
  68. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/level.py +0 -0
  69. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/manifest.py +0 -0
  70. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/__init__.py +0 -0
  71. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/report.py +0 -0
  72. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/runner.py +0 -0
  73. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/tuner.py +0 -0
  74. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/project.py +0 -0
  75. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/py.typed +0 -0
  76. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/rules.py +0 -0
  77. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sfx.py +0 -0
  78. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/__init__.py +0 -0
  79. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/ai.py +0 -0
  80. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/cartoon_monsters.py +0 -0
  81. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/chibi.py +0 -0
  82. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/contour.py +0 -0
  83. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/creatures.py +0 -0
  84. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/importer.py +0 -0
  85. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/items.py +0 -0
  86. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/monsters.py +0 -0
  87. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/motion.py +0 -0
  88. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/palettes.py +0 -0
  89. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/scenery.py +0 -0
  90. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/spriteset.py +0 -0
  91. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/tiles.py +0 -0
  92. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/__init__.py +0 -0
  93. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/creative.py +0 -0
  94. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/dataset.py +0 -0
  95. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/edits.py +0 -0
  96. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/genres.py +0 -0
  97. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/llm.py +0 -0
  98. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/orchestrator.py +0 -0
  99. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/web.py +0 -0
  100. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio_cli.py +0 -0
  101. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/dependency_links.txt +0 -0
  102. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/entry_points.txt +0 -0
  103. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/requires.txt +0 -0
  104. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/top_level.txt +0 -0
  105. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/conftest.py +0 -0
  106. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_ai_sprites.py +0 -0
  107. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_analyze.py +0 -0
  108. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_cockpit.py +0 -0
  109. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_demo.py +0 -0
  110. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_e2e.py +0 -0
  111. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_expr.py +0 -0
  112. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_gif.py +0 -0
  113. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_godot_library.py +0 -0
  114. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_graph.py +0 -0
  115. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_level.py +0 -0
  116. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_live_llm.py +0 -0
  117. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_manifest.py +0 -0
  118. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_playtest.py +0 -0
  119. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_rules.py +0 -0
  120. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_sfx.py +0 -0
  121. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_web.py +0 -0
  122. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/castle_defense.json +0 -0
  123. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/coin_hopper.json +0 -0
  124. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/dino_eggs.json +0 -0
  125. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/knight_quest.json +0 -0
  126. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/neon_arena.json +0 -0
  127. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/night_survivor.json +0 -0
  128. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/ninja_rescue.json +0 -0
  129. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/pixel_arena.json +0 -0
  130. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/pixel_hopper.json +0 -0
  131. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/star_run.json +0 -0
  132. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/aim_component.gd +0 -0
  133. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/base_component.gd +0 -0
  134. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/bubble_board_component.gd +0 -0
  135. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/chase_ai_component.gd +0 -0
  136. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/collectible_component.gd +0 -0
  137. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/crop_pest_component.gd +0 -0
  138. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/experience_component.gd +0 -0
  139. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/flight_path_component.gd +0 -0
  140. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/gate_component.gd +0 -0
  141. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/ground_patch_component.gd +0 -0
  142. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/health_bar_component.gd +0 -0
  143. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/health_component.gd +0 -0
  144. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/hitbox_component.gd +0 -0
  145. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/hurtbox_component.gd +0 -0
  146. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/juice_component.gd +0 -0
  147. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/level_up_menu_component.gd +0 -0
  148. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/path_follower_component.gd +0 -0
  149. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/patrol_ai_component.gd +0 -0
  150. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/platformer_movement_component.gd +0 -0
  151. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/player_input_component.gd +0 -0
  152. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/projectile_component.gd +0 -0
  153. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/shmup_ship_component.gd +0 -0
  154. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/spawner_component.gd +0 -0
  155. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/stomp_component.gd +0 -0
  156. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/top_down_movement_component.gd +0 -0
  157. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_brain_component.gd +0 -0
  158. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_builder_component.gd +0 -0
  159. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_slot_component.gd +0 -0
  160. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/trigger_zone_component.gd +0 -0
  161. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/wave_spawner_component.gd +0 -0
  162. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/weapon_component.gd +0 -0
  163. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/xp_orb_component.gd +0 -0
  164. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/camera_rig.gd +0 -0
  165. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/cockpit.gd +0 -0
  166. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/entity_core.gd +0 -0
  167. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/fx.gd +0 -0
  168. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/hud.gd +0 -0
  169. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/level.gd +0 -0
  170. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/sp.gd +0 -0
  171. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/world.gd +0 -0
  172. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/shaders/flash.gdshader +0 -0
  173. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/shaders/floor_grid.gdshader +0 -0
  174. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/build.tscn +0 -0
  175. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/capture.gd +0 -0
  176. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/capture.tscn +0 -0
  177. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/dump_manifest.gd +0 -0
  178. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/dump_manifest.tscn +0 -0
  179. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest.gd +0 -0
  180. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest.tscn +0 -0
  181. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest_nav.gd +0 -0
  182. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/record.tscn +0 -0
  183. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/smoke.gd +0 -0
  184. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/smoke.tscn +0 -0
  185. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/setup.cfg +0 -0
  186. {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spawnpoint-studio
3
- Version: 0.3.3
3
+ Version: 0.3.5
4
4
  Summary: Turn a sentence into a juicy, playable Godot 4 game — locally, on a consumer GPU.
5
5
  Author: smoky1496
6
6
  License: MIT
@@ -22,6 +22,8 @@ Provides-Extra: dev
22
22
  Requires-Dist: pytest>=7; extra == "dev"
23
23
  Dynamic: license-file
24
24
 
25
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/logo.png" width="520" alt="Spawn Point: a sprout growing out of a glowing spawn pad, and the name in gold pixel letters"></p>
26
+
25
27
  # Spawn Point
26
28
 
27
29
  **Describe a 2D game in one sentence — get a playable, juicy Godot 4 game in seconds.**
@@ -31,23 +33,22 @@ Dynamic: license-file
31
33
  [![Model](https://img.shields.io/badge/%F0%9F%A4%97%20model-SpawnPoint--Coder--7B-yellow)](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
32
34
  [![Play the demos](https://img.shields.io/badge/%E2%96%B6%20play-demos%20in%20your%20browser-ff004d)](https://leluong141996-dev.github.io/Spawn-Point/)
33
35
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
36
+ [![GitHub stars](https://img.shields.io/github/stars/leluong141996-dev/Spawn-Point?style=social)](https://github.com/leluong141996-dev/Spawn-Point/stargazers)
37
+
38
+ ⭐ **If Spawn Point drew something fun or useful, a star helps other people find it. If it drew something wrong, [open an issue](https://github.com/leluong141996-dev/Spawn-Point/issues/new) with your prompt: the model's tests grow from prompts that broke.**
34
39
 
35
40
  <p align="center">
36
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/knight-quest.gif" width="48%" alt="Knight's Quest: a sword platformer">
37
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/castle-defense.gif" width="48%" alt="Castle Defense: a tower defense game">
38
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/ninja-rescue.gif" width="48%" alt="Ninja Rescue: a platformer where a ninja frees his mother">
39
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/dino-eggs.gif" width="48%" alt="Dino Eggs: a bubble shooter with dinosaur eggs">
40
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/night-survivor.gif" width="48%" alt="Night Survivor: auto-fire, gems, level-ups">
41
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/pixel-hopper.gif" width="48%" alt="Pixel Hopper: a Mario-style platformer">
42
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/star-run.gif" width="48%" alt="Star Run: a side-scrolling shooter with power-ups and a boss">
41
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-field.gif" width="48%" alt="Tilling, planting, watering and harvesting in the fenced field">
42
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-animals.gif" width="48%" alt="Collecting eggs and milk from the chickens and the cow in the pen">
43
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-fishing.gif" width="48%" alt="Fishing from the pond's shore: cast, wait for the bite, reel in">
44
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-house.gif" width="48%" alt="Walking into the farmhouse: bed, fireplace, table and rug">
43
45
  </p>
44
- <p align="center"><sub>Seven of the demo games, each one a small JSON graph in <code>examples/</code> built from the
45
- same component library: generated pixel art, collision traced from the sprites, juice on by default.
46
- Recorded with <code>spawnpoint gif</code> (autopilot).</sub></p>
46
+ <p align="center"><sub>A cozy farm made from one sentence: the field, the animals, fishing and the farmhouse inside.
47
+ Every tile, building, animal and crop is drawn by plain Python. Recorded with <code>spawnpoint gif --focus field|animals|fish|house</code> (autopilot).</sub></p>
47
48
 
48
49
  <p align="center"><b><a href="https://leluong141996-dev.github.io/Spawn-Point/">▶ Play the demos in your browser</a></b>: a Mario-style platformer, a
49
- knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a farming
50
- game, an arena shooter and a side-scrolling space shooter. No install needed, and
50
+ knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a cozy
51
+ island farm, an arena shooter and a side-scrolling space shooter. No install needed, and
51
52
  they work on phones too (touch controls).</p>
52
53
 
53
54
  Spawn Point is an open-source, autonomous game studio that runs on your own machine. Instead of asking an LLM to type
@@ -156,7 +157,7 @@ Only what you asked for changes, and the level layout is kept. Prompts can be in
156
157
  **The model.** [SpawnPoint-Coder-7B](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ) is a 7B model
157
158
  fine-tuned to generate Godot 4 games through this pipeline: it writes the game design, tweaks and entity
158
159
  edits as strict JSON, and the compiler turns that into Godot scenes and GDScript. It runs on a single 12 GB
159
- GPU (AWQ 4-bit). v5 added **side-scrolling shooters** (flight patterns, power-ups, a boss), **Vietnamese prompts read directly** and a small per-genre format instead of one big form; v5.1 fixes prompts that name the hero only indirectly ("a tank shooting monsters"). The downloadable AWQ build gets 88% of a sealed set of 16 human-written prompts for shooters and the v4 fixes fully right, and 80% of 30 human-written game ideas in English and Vietnamese (v4: 87% on those 30; the model card lists every number and where v5.1 is behind). The GGUF Q4_K_M build scores 83% on those 30. Older models still work with `SPAWNPOINT_BRIEF_FORMAT=v4`. It is tuned for the 2D game kinds Spawn Point builds; other genres are no better than a general 7B coder. `spawnpoint llm up` downloads and serves it: the AWQ build on vLLM when
160
+ GPU (AWQ 4-bit). v5 added **side-scrolling shooters** (flight patterns, power-ups, a boss), **Vietnamese prompts read directly** and a small per-genre format instead of one big form; v5.1 fixes prompts that name the hero only indirectly ("a tank shooting monsters"); v5.2 catches farm pests mentioned only in passing ("có cáo", "with a fox around") and leaves peaceful farms without any. The downloadable AWQ build gets 94% of a sealed set of 16 human-written prompts for shooters and the v4 fixes fully right, 100% of a sealed set of 16 farm prompts with pests named in passing, and 83% of 30 human-written game ideas in English and Vietnamese (v4: 87% on those 30; the model card lists every number and where v5.2 is behind). The GGUF Q4_K_M build scores 87% on those 30. Older models still work with `SPAWNPOINT_BRIEF_FORMAT=v4`. It is tuned for the 2D game kinds Spawn Point builds; other genres are no better than a general 7B coder. `spawnpoint llm up` downloads and serves it: the AWQ build on vLLM when
160
161
  Docker and an NVIDIA GPU are present, otherwise the [GGUF build](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-GGUF)
161
162
  (Q4_K_M, ~4.7 GB) in Ollama. Force one with `--backend vllm|ollama`.
162
163
 
@@ -167,12 +168,53 @@ Web builds need the Godot **web export templates** (Editor → Manage Export Tem
167
168
  `web_*.zip` from the official `.tpz` into `~/.local/share/godot/export_templates/<version>/`);
168
169
  use `--no-web` to skip and play natively with `spawnpoint run`.
169
170
 
171
+ ## A cozy farm from one sentence
172
+
173
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-overview.png" width="92%" alt="A generated island farm: farmhouse, fenced crop field, animal pen with a coop, pond and woods"><br><sub>One generated farm, the whole map: everything here is drawn by plain Python, no image files.</sub></p>
174
+
175
+ Ask for a farming game (`spawnpoint create "a cozy farming game with strawberries and pumpkins"`) and
176
+ Spawn Point lays out a whole farm: a farmhouse with a dirt path to its door, a fenced crop field, an animal pen with a
177
+ coop, a pond, a shipping bin, and woods around the edge, on an island (water all round, cliffs to the south; an
178
+ ocean-themed farm always is one) or in a meadow in the woods. The art is a 16-pixel tile set drawn from code: grass with tufts, flowers and mushrooms, paths with soft edges,
179
+ water with lily pads and reeds, buildings, fences, four kinds of tree, chickens and cows, a farmer who walks in four
180
+ directions, and crops with five growth stages (strawberries, carrots, potatoes, pumpkins, corn, wheat, cabbages...,
181
+ picked from the crop's name).
182
+
183
+ A farm is a season of a few days, each running from 6:00 to 22:00 with the light turning gold in the evening and dark
184
+ at night; sleep in the farmhouse bed (or drop off in the fields at midnight) and watered crops grow overnight. Earn the
185
+ target before the season ends. What you do there: buy seeds (they cost money), till the grass with the hoe, plant,
186
+ water and harvest; feed the hens and the cow, then collect eggs and milk (chicks grow into hens); fish from the pond's
187
+ shore (cast, wait for the bite, reel in on the "!"); chop trees and break rocks for wood and stone; carry it all to the
188
+ shipping bin, while crows, foxes, rabbits or mice go for your crops. Step through the farmhouse door for a cozy room
189
+ inside (bed, fireplace, table, rug). Maps vary: the house on either side, the field and the pen swapping places, the
190
+ pond moving around. The workbench by the house sells tool upgrades (a watering can and a hoe that work a
191
+ 3x3 patch, a bigger basket, a sharper axe, a better rod), and the farm saves itself: close the game and it carries on
192
+ where you left it (a won or lost season, or R, starts a fresh one). Some days it rains and the crops water themselves
193
+ (snow on a winter farm); a shop stall sells hens, cows, golden melon seeds and sprinklers that water their patch every
194
+ morning. A farm opens on a title screen (carry on, or N for a new farm), P pauses, and each season has its own little
195
+ chiptune, composed at build time. On a phone, ACT does all of it, a tap on a seed in the bar picks it, and II pauses. The
196
+ hotbar shows your seeds and basket. You walk behind trees and the house (the scene is depth-sorted), and only an
197
+ object's footprint blocks you. `spawnpoint overview <project>` saves a picture of the whole map after a short autopilot
198
+ run, like the one above.
199
+
200
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/sunny-farm.gif" width="52%" alt="Sunny Farm: the farmer harvests, sells at the shipping bin and works the field"> <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-night.gif" width="40%" alt="Evening turns to night on the farm; the farmer milks the cow before bed"></p>
201
+
202
+ The theme sets the season, and the model picks it from the prompt ("a winter farm", "nông trại trên sa mạc"): a snowy
203
+ farm is winter (snow, a frozen pond, snowy pines and bare trees, and crops grow slower), a desert farm has sand, palms
204
+ and cacti (and the soil dries faster), an autumn farm is orange with maples, the rest is spring.
205
+
206
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-seasons.png" width="92%" alt="The same kind of farm in spring, autumn, winter and the desert"></p>
207
+ <p align="center">
208
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-winter.gif" width="32%" alt="A winter farm: snow, snowy pines, bare trees">
209
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-autumn.gif" width="32%" alt="An autumn farm: orange ground, maples">
210
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-desert.gif" width="32%" alt="A desert farm: sand, palms and cacti">
211
+ </p>
212
+
170
213
  ## Sprites: generated or your own
171
214
 
172
215
  Layer 2 replaces placeholder shapes with **procedural pixel art** — no assets, no GPU: chibi people with big heads, monsters with faces (a biting plant, a mushroom, a snail, a flame spirit, a reaper, an alien, a dragon, a ghost...), items, props, themed tiles and a parallax sky. Spawn Point makes pixel art games only. (A graph can still ask for the smooth `"art_style": "cartoon"` look by hand, but games made from a prompt are always pixel art.)
173
216
 
174
- <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/parade-heroes.gif" width="48%" alt="Animated heroes: knight, wizard, ranger, viking, king, princess, ninja..."> <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/parade-monsters.gif" width="48%" alt="Animated monsters: slime, frog, biting plant, mushroom, snail, flame..."></p>
175
- <p align="center"><sub>Every character and monster is drawn by plain Python from its name (<code>spawnpoint sprites parade --set heroes|monsters|items</code>).</sub></p>
217
+ Every character and monster is drawn by plain Python from its name; `spawnpoint sprites parade --set heroes|monsters|items` renders them as an animated sheet.
176
218
 
177
219
  The
178
220
  kind follows the entity (`Goblin` → humanoid, `FireBat` → flyer, `LaserBot` → robot, `Crystal` → gem…)
@@ -217,7 +259,7 @@ match the palette, drawn behind everything and without collision.
217
259
  Record a clip of any built game to share it (a window opens for a few seconds; autopilot plays):
218
260
 
219
261
  ```bash
220
- spawnpoint gif out/pixel-hopper -o demo.gif --seconds 8 --fps 20 --width 640
262
+ spawnpoint gif out/sunny-farm -o demo.gif --seconds 10 --fps 10 --focus fish
221
263
  ```
222
264
 
223
265
  **AI art (optional plug-in).** Point Spawn Point at an image model and layer 2 asks it for the look of
@@ -369,7 +411,7 @@ headless smoke test (spawn, scripted input, crash detection) and report `E_RUNTI
369
411
  | Game modes | `BubbleBoard` (a complete bubble shooter: bank shots, colour pops, falling clusters, a descending ceiling) |
370
412
  | Shooters | `FlightPath` (straight, wave, dive and hover patterns across the screen), `ShmupShip` (auto-fire, power-ups that add shots and spread), `HealthBar` (boss bars), and `WaveSpawner` gates (`autostart`, `endless`, random spread) |
371
413
  | Tower defense | `PathFollower` (walks the road to the base), `Base` (loses a life per invader that gets in), `WaveSpawner` ("8 x Goblin every 1.2; ..."), `TowerSlot`, `TowerBuilder` (click a pad, pay in gold), `TowerBrain` (targets the invader furthest along), `GroundPatch` (roads and paths) |
372
- | Farming | `FarmPlot` (soil that grows a crop only while watered), `Farmer` (plant / water / harvest, a basket, crop choice), `Market` (sell the basket), `CropPest` (crows that eat crops) |
414
+ | Farming | `FarmPlot` (soil that grows a crop only while watered, drawn from its growth stages), `Farmer` (till / plant / water / harvest, buy seeds, feed, collect, fish, chop, sleep, a basket and a tappable hotbar), `FarmAnimal` (wanders, needs feeding, gives eggs or milk, chicks grow up), `FarmDays` (a season of days with day and night), `SleepSpot` (a bed), `ToolBench` (tool upgrades), `FarmSave` (keeps the farm between plays), `Shop` and `Sprinkler` (buy animals, seeds and sprinklers), `GameMenu` (title screen, pause menu, music), `Gatherable` (trees and rocks that break into wood and stone), `FishingSpot` (cast, bite, reel in), `Warp` (doorways, e.g. into the farmhouse), `Market` (a stall or a shipping bin that buys the basket), `CropPest` (crows that eat crops) |
373
415
  | Feel | `Juice` — attached to every entity unless `"juice": "none"` |
374
416
 
375
417
  Runtime autoloads: `GameState` (score, lives, variables, win/lose), `World` (spawning, rule
@@ -1,3 +1,5 @@
1
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/logo.png" width="520" alt="Spawn Point: a sprout growing out of a glowing spawn pad, and the name in gold pixel letters"></p>
2
+
1
3
  # Spawn Point
2
4
 
3
5
  **Describe a 2D game in one sentence — get a playable, juicy Godot 4 game in seconds.**
@@ -7,23 +9,22 @@
7
9
  [![Model](https://img.shields.io/badge/%F0%9F%A4%97%20model-SpawnPoint--Coder--7B-yellow)](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
8
10
  [![Play the demos](https://img.shields.io/badge/%E2%96%B6%20play-demos%20in%20your%20browser-ff004d)](https://leluong141996-dev.github.io/Spawn-Point/)
9
11
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
12
+ [![GitHub stars](https://img.shields.io/github/stars/leluong141996-dev/Spawn-Point?style=social)](https://github.com/leluong141996-dev/Spawn-Point/stargazers)
13
+
14
+ ⭐ **If Spawn Point drew something fun or useful, a star helps other people find it. If it drew something wrong, [open an issue](https://github.com/leluong141996-dev/Spawn-Point/issues/new) with your prompt: the model's tests grow from prompts that broke.**
10
15
 
11
16
  <p align="center">
12
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/knight-quest.gif" width="48%" alt="Knight's Quest: a sword platformer">
13
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/castle-defense.gif" width="48%" alt="Castle Defense: a tower defense game">
14
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/ninja-rescue.gif" width="48%" alt="Ninja Rescue: a platformer where a ninja frees his mother">
15
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/dino-eggs.gif" width="48%" alt="Dino Eggs: a bubble shooter with dinosaur eggs">
16
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/night-survivor.gif" width="48%" alt="Night Survivor: auto-fire, gems, level-ups">
17
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/pixel-hopper.gif" width="48%" alt="Pixel Hopper: a Mario-style platformer">
18
- <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/star-run.gif" width="48%" alt="Star Run: a side-scrolling shooter with power-ups and a boss">
17
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-field.gif" width="48%" alt="Tilling, planting, watering and harvesting in the fenced field">
18
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-animals.gif" width="48%" alt="Collecting eggs and milk from the chickens and the cow in the pen">
19
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-fishing.gif" width="48%" alt="Fishing from the pond's shore: cast, wait for the bite, reel in">
20
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-house.gif" width="48%" alt="Walking into the farmhouse: bed, fireplace, table and rug">
19
21
  </p>
20
- <p align="center"><sub>Seven of the demo games, each one a small JSON graph in <code>examples/</code> built from the
21
- same component library: generated pixel art, collision traced from the sprites, juice on by default.
22
- Recorded with <code>spawnpoint gif</code> (autopilot).</sub></p>
22
+ <p align="center"><sub>A cozy farm made from one sentence: the field, the animals, fishing and the farmhouse inside.
23
+ Every tile, building, animal and crop is drawn by plain Python. Recorded with <code>spawnpoint gif --focus field|animals|fish|house</code> (autopilot).</sub></p>
23
24
 
24
25
  <p align="center"><b><a href="https://leluong141996-dev.github.io/Spawn-Point/">▶ Play the demos in your browser</a></b>: a Mario-style platformer, a
25
- knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a farming
26
- game, an arena shooter and a side-scrolling space shooter. No install needed, and
26
+ knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a cozy
27
+ island farm, an arena shooter and a side-scrolling space shooter. No install needed, and
27
28
  they work on phones too (touch controls).</p>
28
29
 
29
30
  Spawn Point is an open-source, autonomous game studio that runs on your own machine. Instead of asking an LLM to type
@@ -132,7 +133,7 @@ Only what you asked for changes, and the level layout is kept. Prompts can be in
132
133
  **The model.** [SpawnPoint-Coder-7B](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ) is a 7B model
133
134
  fine-tuned to generate Godot 4 games through this pipeline: it writes the game design, tweaks and entity
134
135
  edits as strict JSON, and the compiler turns that into Godot scenes and GDScript. It runs on a single 12 GB
135
- GPU (AWQ 4-bit). v5 added **side-scrolling shooters** (flight patterns, power-ups, a boss), **Vietnamese prompts read directly** and a small per-genre format instead of one big form; v5.1 fixes prompts that name the hero only indirectly ("a tank shooting monsters"). The downloadable AWQ build gets 88% of a sealed set of 16 human-written prompts for shooters and the v4 fixes fully right, and 80% of 30 human-written game ideas in English and Vietnamese (v4: 87% on those 30; the model card lists every number and where v5.1 is behind). The GGUF Q4_K_M build scores 83% on those 30. Older models still work with `SPAWNPOINT_BRIEF_FORMAT=v4`. It is tuned for the 2D game kinds Spawn Point builds; other genres are no better than a general 7B coder. `spawnpoint llm up` downloads and serves it: the AWQ build on vLLM when
136
+ GPU (AWQ 4-bit). v5 added **side-scrolling shooters** (flight patterns, power-ups, a boss), **Vietnamese prompts read directly** and a small per-genre format instead of one big form; v5.1 fixes prompts that name the hero only indirectly ("a tank shooting monsters"); v5.2 catches farm pests mentioned only in passing ("có cáo", "with a fox around") and leaves peaceful farms without any. The downloadable AWQ build gets 94% of a sealed set of 16 human-written prompts for shooters and the v4 fixes fully right, 100% of a sealed set of 16 farm prompts with pests named in passing, and 83% of 30 human-written game ideas in English and Vietnamese (v4: 87% on those 30; the model card lists every number and where v5.2 is behind). The GGUF Q4_K_M build scores 87% on those 30. Older models still work with `SPAWNPOINT_BRIEF_FORMAT=v4`. It is tuned for the 2D game kinds Spawn Point builds; other genres are no better than a general 7B coder. `spawnpoint llm up` downloads and serves it: the AWQ build on vLLM when
136
137
  Docker and an NVIDIA GPU are present, otherwise the [GGUF build](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-GGUF)
137
138
  (Q4_K_M, ~4.7 GB) in Ollama. Force one with `--backend vllm|ollama`.
138
139
 
@@ -143,12 +144,53 @@ Web builds need the Godot **web export templates** (Editor → Manage Export Tem
143
144
  `web_*.zip` from the official `.tpz` into `~/.local/share/godot/export_templates/<version>/`);
144
145
  use `--no-web` to skip and play natively with `spawnpoint run`.
145
146
 
147
+ ## A cozy farm from one sentence
148
+
149
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-overview.png" width="92%" alt="A generated island farm: farmhouse, fenced crop field, animal pen with a coop, pond and woods"><br><sub>One generated farm, the whole map: everything here is drawn by plain Python, no image files.</sub></p>
150
+
151
+ Ask for a farming game (`spawnpoint create "a cozy farming game with strawberries and pumpkins"`) and
152
+ Spawn Point lays out a whole farm: a farmhouse with a dirt path to its door, a fenced crop field, an animal pen with a
153
+ coop, a pond, a shipping bin, and woods around the edge, on an island (water all round, cliffs to the south; an
154
+ ocean-themed farm always is one) or in a meadow in the woods. The art is a 16-pixel tile set drawn from code: grass with tufts, flowers and mushrooms, paths with soft edges,
155
+ water with lily pads and reeds, buildings, fences, four kinds of tree, chickens and cows, a farmer who walks in four
156
+ directions, and crops with five growth stages (strawberries, carrots, potatoes, pumpkins, corn, wheat, cabbages...,
157
+ picked from the crop's name).
158
+
159
+ A farm is a season of a few days, each running from 6:00 to 22:00 with the light turning gold in the evening and dark
160
+ at night; sleep in the farmhouse bed (or drop off in the fields at midnight) and watered crops grow overnight. Earn the
161
+ target before the season ends. What you do there: buy seeds (they cost money), till the grass with the hoe, plant,
162
+ water and harvest; feed the hens and the cow, then collect eggs and milk (chicks grow into hens); fish from the pond's
163
+ shore (cast, wait for the bite, reel in on the "!"); chop trees and break rocks for wood and stone; carry it all to the
164
+ shipping bin, while crows, foxes, rabbits or mice go for your crops. Step through the farmhouse door for a cozy room
165
+ inside (bed, fireplace, table, rug). Maps vary: the house on either side, the field and the pen swapping places, the
166
+ pond moving around. The workbench by the house sells tool upgrades (a watering can and a hoe that work a
167
+ 3x3 patch, a bigger basket, a sharper axe, a better rod), and the farm saves itself: close the game and it carries on
168
+ where you left it (a won or lost season, or R, starts a fresh one). Some days it rains and the crops water themselves
169
+ (snow on a winter farm); a shop stall sells hens, cows, golden melon seeds and sprinklers that water their patch every
170
+ morning. A farm opens on a title screen (carry on, or N for a new farm), P pauses, and each season has its own little
171
+ chiptune, composed at build time. On a phone, ACT does all of it, a tap on a seed in the bar picks it, and II pauses. The
172
+ hotbar shows your seeds and basket. You walk behind trees and the house (the scene is depth-sorted), and only an
173
+ object's footprint blocks you. `spawnpoint overview <project>` saves a picture of the whole map after a short autopilot
174
+ run, like the one above.
175
+
176
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/sunny-farm.gif" width="52%" alt="Sunny Farm: the farmer harvests, sells at the shipping bin and works the field"> <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-night.gif" width="40%" alt="Evening turns to night on the farm; the farmer milks the cow before bed"></p>
177
+
178
+ The theme sets the season, and the model picks it from the prompt ("a winter farm", "nông trại trên sa mạc"): a snowy
179
+ farm is winter (snow, a frozen pond, snowy pines and bare trees, and crops grow slower), a desert farm has sand, palms
180
+ and cacti (and the soil dries faster), an autumn farm is orange with maples, the rest is spring.
181
+
182
+ <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-seasons.png" width="92%" alt="The same kind of farm in spring, autumn, winter and the desert"></p>
183
+ <p align="center">
184
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-winter.gif" width="32%" alt="A winter farm: snow, snowy pines, bare trees">
185
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-autumn.gif" width="32%" alt="An autumn farm: orange ground, maples">
186
+ <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/farm-desert.gif" width="32%" alt="A desert farm: sand, palms and cacti">
187
+ </p>
188
+
146
189
  ## Sprites: generated or your own
147
190
 
148
191
  Layer 2 replaces placeholder shapes with **procedural pixel art** — no assets, no GPU: chibi people with big heads, monsters with faces (a biting plant, a mushroom, a snail, a flame spirit, a reaper, an alien, a dragon, a ghost...), items, props, themed tiles and a parallax sky. Spawn Point makes pixel art games only. (A graph can still ask for the smooth `"art_style": "cartoon"` look by hand, but games made from a prompt are always pixel art.)
149
192
 
150
- <p align="center"><img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/parade-heroes.gif" width="48%" alt="Animated heroes: knight, wizard, ranger, viking, king, princess, ninja..."> <img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/parade-monsters.gif" width="48%" alt="Animated monsters: slime, frog, biting plant, mushroom, snail, flame..."></p>
151
- <p align="center"><sub>Every character and monster is drawn by plain Python from its name (<code>spawnpoint sprites parade --set heroes|monsters|items</code>).</sub></p>
193
+ Every character and monster is drawn by plain Python from its name; `spawnpoint sprites parade --set heroes|monsters|items` renders them as an animated sheet.
152
194
 
153
195
  The
154
196
  kind follows the entity (`Goblin` → humanoid, `FireBat` → flyer, `LaserBot` → robot, `Crystal` → gem…)
@@ -193,7 +235,7 @@ match the palette, drawn behind everything and without collision.
193
235
  Record a clip of any built game to share it (a window opens for a few seconds; autopilot plays):
194
236
 
195
237
  ```bash
196
- spawnpoint gif out/pixel-hopper -o demo.gif --seconds 8 --fps 20 --width 640
238
+ spawnpoint gif out/sunny-farm -o demo.gif --seconds 10 --fps 10 --focus fish
197
239
  ```
198
240
 
199
241
  **AI art (optional plug-in).** Point Spawn Point at an image model and layer 2 asks it for the look of
@@ -345,7 +387,7 @@ headless smoke test (spawn, scripted input, crash detection) and report `E_RUNTI
345
387
  | Game modes | `BubbleBoard` (a complete bubble shooter: bank shots, colour pops, falling clusters, a descending ceiling) |
346
388
  | Shooters | `FlightPath` (straight, wave, dive and hover patterns across the screen), `ShmupShip` (auto-fire, power-ups that add shots and spread), `HealthBar` (boss bars), and `WaveSpawner` gates (`autostart`, `endless`, random spread) |
347
389
  | Tower defense | `PathFollower` (walks the road to the base), `Base` (loses a life per invader that gets in), `WaveSpawner` ("8 x Goblin every 1.2; ..."), `TowerSlot`, `TowerBuilder` (click a pad, pay in gold), `TowerBrain` (targets the invader furthest along), `GroundPatch` (roads and paths) |
348
- | Farming | `FarmPlot` (soil that grows a crop only while watered), `Farmer` (plant / water / harvest, a basket, crop choice), `Market` (sell the basket), `CropPest` (crows that eat crops) |
390
+ | Farming | `FarmPlot` (soil that grows a crop only while watered, drawn from its growth stages), `Farmer` (till / plant / water / harvest, buy seeds, feed, collect, fish, chop, sleep, a basket and a tappable hotbar), `FarmAnimal` (wanders, needs feeding, gives eggs or milk, chicks grow up), `FarmDays` (a season of days with day and night), `SleepSpot` (a bed), `ToolBench` (tool upgrades), `FarmSave` (keeps the farm between plays), `Shop` and `Sprinkler` (buy animals, seeds and sprinklers), `GameMenu` (title screen, pause menu, music), `Gatherable` (trees and rocks that break into wood and stone), `FishingSpot` (cast, bite, reel in), `Warp` (doorways, e.g. into the farmhouse), `Market` (a stall or a shipping bin that buys the basket), `CropPest` (crows that eat crops) |
349
391
  | Feel | `Juice` — attached to every entity unless `"juice": "none"` |
350
392
 
351
393
  Runtime autoloads: `GameState` (score, lives, variables, win/lose), `World` (spawning, rule
@@ -9,7 +9,7 @@ from typing import Any
9
9
 
10
10
  from . import level as lvl
11
11
  from .diagnostics import Diagnostics, did_you_mean, join_path
12
- from .graph import Entity, Graph, parse
12
+ from .graph import Entity, Graph, Shape, parse
13
13
  from .manifest import BODY_CLASSES, Component, Manifest, Param
14
14
  from .rules import compile_rules
15
15
  from .sprites import resolve as sprite_resolve
@@ -121,7 +121,11 @@ class _Analyzer:
121
121
  "Generator kinds: " + ", ".join(sorted(sprite_resolve.KINDS)) if "kind" in str(e) else None)
122
122
  continue
123
123
  self.sprites[name] = sprite
124
- if "shape" not in ent.model_fields_set:
124
+ if ent.base is not None and "shape" not in ent.model_fields_set:
125
+ # Standing on its base: only the footprint collides (walk behind the crown or the roof).
126
+ ent.shape = Shape(type="circle" if ent.body == "character" else "rect", size=tuple(ent.base),
127
+ color=ent.shape.color)
128
+ elif "shape" not in ent.model_fields_set:
125
129
  # No explicit shape: the body collision comes from the drawing.
126
130
  ent.shape = sprite_resolve.derived_shape(ent, sprite, self.g.genre)
127
131
 
@@ -130,6 +134,12 @@ class _Analyzer:
130
134
  s = self.g.settings
131
135
  from .sprites import scenery as sc
132
136
 
137
+ for name, req in s.art.items():
138
+ self.scenery_images[f"art_{name}"] = sc.to_image(_draw_art(req))
139
+ if s.terrain: # a drawn ground for the whole map (farms)
140
+ from .sprites import farm
141
+ self.scenery_images["scenery_ground"] = sc.to_image(farm.terrain_image(s.terrain, s.seed, s.season))
142
+ return {"ground": "res://sprites/scenery_ground.png", "pixel": 2}
133
143
  if s.scenery == "space": # scrolling stars for shooters, in any art style
134
144
  sky, stars = sc.space(background, s.pixel_palette if s.art_style == "pixel" else None, s.seed)
135
145
  self.scenery_images["scenery_sky"] = sc.to_image(sky)
@@ -346,9 +356,11 @@ class _Analyzer:
346
356
  "color": ent.shape.color or self._color(ent, team)},
347
357
  "eye": ent.body == "character" and sprite is None,
348
358
  "pivot": "bottom" if g.genre == "platformer" and ent.body == "character" else "center",
349
- "sprite": sprite_resolve.plan_entry(name, sprite) if sprite is not None else None,
359
+ "sprite": sprite_resolve.plan_entry(name, sprite, on_base=ent.base is not None) if sprite is not None else None,
350
360
  "z": -1 if ent.decor else 0,
351
361
  })
362
+ if ent.base is not None: # the collision box sits at the feet, the origin
363
+ entities[-1]["shape_offset"] = [0, round(-ent.shape.size[1] / 2, 2)]
352
364
  entities[-1]["components"] = comps
353
365
 
354
366
  placements = []
@@ -356,7 +368,9 @@ class _Analyzer:
356
368
  ent = g.entities[p.entity]
357
369
  x = (p.x + 0.5) * ts
358
370
  floating = any(c in ent.components for c in ("Collectible", "Projectile", "Spawner"))
359
- if g.genre == "platformer" and not floating:
371
+ if ent.base is not None: # standing on the bottom of its cell
372
+ y = (p.y + 1) * ts - 4
373
+ elif g.genre == "platformer" and not floating:
360
374
  y = (p.y + 1) * ts - ent.shape.size[1] / 2
361
375
  else:
362
376
  y = (p.y + 0.5) * ts
@@ -410,6 +424,7 @@ class _Analyzer:
410
424
  "walls": self.genre["walls"],
411
425
  "entities": entities,
412
426
  "placements": placements,
427
+ "y_sort": s.y_sort,
413
428
  "rules_script": RULES_SCRIPT,
414
429
  }
415
430
 
@@ -446,3 +461,15 @@ class _Analyzer:
446
461
  if team == "enemy":
447
462
  return COLORS["enemy"]
448
463
  return COLORS["other"]
464
+
465
+
466
+ def _draw_art(req):
467
+ """The picture an ArtRequest asks for, as an RGBA array."""
468
+ from .sprites import farm
469
+ if req.kind == "crop":
470
+ return farm.crop_sheet(req.of, req.color or "#e83a4a")
471
+ if req.kind == "crop_icon":
472
+ return farm.crop_icon(req.of, req.color or "#e83a4a")
473
+ if req.kind == "item_icon":
474
+ return farm.item_icon(req.of)
475
+ return farm.soil_tile(req.kind == "soil_wet")
@@ -9,7 +9,7 @@ from dataclasses import dataclass, field
9
9
  from pathlib import Path
10
10
  from typing import Any
11
11
 
12
- from . import godot, manifest as manifest_mod, project, sfx
12
+ from . import godot, manifest as manifest_mod, music, project, sfx
13
13
  from .analyze import Analysis, analyze
14
14
  from .diagnostics import Diagnostics
15
15
  from .manifest import Manifest
@@ -68,6 +68,8 @@ def build(data: Any, out_dir: Path, *, manifest: Manifest | None = None, smoke:
68
68
  project.write(out_dir, data, plan, analysis.rules_source, feature, analysis.sprites, analysis.tiles_image,
69
69
  analysis.scenery_images)
70
70
  sfx.write_all(out_dir / "sfx", seed=analysis.graph.settings.seed)
71
+ if analysis.graph.settings.music != "none":
72
+ music.write(out_dir / "sfx", analysis.graph.settings.music, analysis.graph.settings.seed)
71
73
  timings["write"] = time.perf_counter() - t
72
74
 
73
75
  log: list[str] = []
@@ -94,6 +94,16 @@ def main(argv: list[str] | None = None) -> int:
94
94
  gf.add_argument("--fps", type=int, default=20)
95
95
  gf.add_argument("--width", type=int, default=640)
96
96
  gf.add_argument("--skip", type=float, default=0.0, help="seconds of play before the clip starts")
97
+ gf.add_argument("--focus", default="", choices=["", "field", "animals", "fish", "house"],
98
+ help="farms: show one activity")
99
+
100
+ lg = sub.add_parser("logo", help="write the Spawn Point pixel-art logo (icons, wordmark, favicon)")
101
+ lg.add_argument("-o", "--out", type=Path, default=Path("logo"))
102
+
103
+ ov = sub.add_parser("overview", help="save one picture of a built project's whole map (needs a display)")
104
+ ov.add_argument("project", type=Path)
105
+ ov.add_argument("-o", "--out", type=Path, help="output file (default: <project>/overview.png)")
106
+ ov.add_argument("--seconds", type=float, default=20.0, help="seconds of autopilot play first")
97
107
 
98
108
  sp = sub.add_parser("sprites", help="import, generate or preview sprites")
99
109
  sps = sp.add_subparsers(dest="sprites_cmd", required=True)
@@ -143,7 +153,7 @@ def main(argv: list[str] | None = None) -> int:
143
153
  return {"validate": _validate, "build": _build, "run": _run, "components": _components,
144
154
  "manifest": _manifest, "create": studio_cli.create, "tweak": studio_cli.tweak,
145
155
  "serve": studio_cli.serve, "dataset": studio_cli.dataset, "playtest": studio_cli.playtest, "studio": studio_cli.studio,
146
- "sprites": _sprites, "gif": _gif, "llm": _llm, "examples": _examples,
156
+ "sprites": _sprites, "gif": _gif, "overview": _overview, "logo": _logo, "llm": _llm, "examples": _examples,
147
157
  "demo": _demo}[args.cmd](args)
148
158
  except godot.GodotError as e:
149
159
  print(f"error: {e}", file=sys.stderr)
@@ -252,11 +262,28 @@ def _gif(args) -> int:
252
262
  from .gif import record_gif
253
263
 
254
264
  out = args.out or args.project / "demo.gif"
255
- path = record_gif(args.project.resolve(), out.resolve(), args.seconds, args.fps, args.width, args.skip)
265
+ path = record_gif(args.project.resolve(), out.resolve(), args.seconds, args.fps, args.width, args.skip, args.focus)
256
266
  print(f"Wrote {out} ({path.stat().st_size / 1e6:.1f} MB)")
257
267
  return 0
258
268
 
259
269
 
270
+ def _logo(args) -> int:
271
+ from .logo import write
272
+
273
+ for path in write(args.out):
274
+ print(f"Wrote {path}")
275
+ return 0
276
+
277
+
278
+ def _overview(args) -> int:
279
+ from .gif import overview
280
+
281
+ out = args.out or args.project / "overview.png"
282
+ overview(args.project.resolve(), out.resolve(), args.seconds)
283
+ print(f"Wrote {out}")
284
+ return 0
285
+
286
+
260
287
  def _demo(args) -> int:
261
288
  from .demo import build_site
262
289
 
@@ -55,10 +55,10 @@ SHOWCASE = [
55
55
  "Move: arrows / WASD | Dash: Shift | Pick an upgrade: 1 / 2 / 3 or click | Restart: R",
56
56
  {"pad": "dpad", "buttons": [["DASH", "ShiftLeft"]], "tap": "Move with the stick - you shoot on your own"}),
57
57
  ("sunny_farm.json", "farming",
58
- "Plant, water and harvest carrots, tomatoes and pumpkins, sell them at the market, and shoo the crows before sunset.",
59
- "Move: arrows / WASD | Plant, water, harvest: Space / E | Crop: 1 / 2 / 3 | Shoo crows: X | Restart: R",
60
- {"pad": "dpad", "buttons": [["ACT", "Space"], ["SHOO", "KeyX"], ["3", "Digit3"], ["2", "Digit2"], ["1", "Digit1"]],
61
- "tap": "Stand next to a plot and press ACT"}),
58
+ "A cozy island farm over three days: buy seeds, till and grow strawberries, carrots and pumpkins, feed the hens and the cow, fish in the pond, chop wood, sleep in the farmhouse, upgrade your tools, buy hens and sprinklers, and sell it all at the shipping bin. Rainy days water the crops; your farm is saved as you play.",
59
+ "Move: arrows / WASD | Till, plant, water, harvest, feed, fish, chop, shop, go in, sleep: Space / E | Seed: 1 / 2 / 3 or click it | Shoo crows: X | Pause: P | Restart: R",
60
+ {"pad": "dpad", "buttons": [["ACT", "Space"], ["SHOO", "KeyX"], ["II", "KeyP"]],
61
+ "tap": "ACT works the field, feeds, fishes and opens doors; tap a seed in the bar to choose it"}),
62
62
  ("pixel_arena.json", "arena shooter",
63
63
  "A top-down arena: blast through robots and turrets, then reach the portal.",
64
64
  "Move: WASD | Aim: mouse | Shoot: click / X | Dash: Shift | Restart: R",
@@ -127,6 +127,8 @@ def build_site(out: Path, games: list[Game] | None = None, screenshots: bool = T
127
127
  share_engine(out, target)
128
128
  log(f" {g.slug}: built (web export {seconds:.1f}s)")
129
129
  shutil.copy2(TOUCH_JS, out / "touch.js") # every game page loads it (before the browser check)
130
+ from . import logo
131
+ logo.write(out) # favicon.ico, logo.png and the icon sizes
130
132
  built = [g for g in games if (out / g.slug / "index.html").exists()]
131
133
  if screenshots:
132
134
  if webcheck.find_chrome() is None:
@@ -205,6 +207,8 @@ def index_html(games: list[Game]) -> str:
205
207
  <meta charset="utf-8">
206
208
  <meta name="viewport" content="width=device-width, initial-scale=1">
207
209
  <title>Spawn Point demos</title>
210
+ <link rel="icon" href="favicon.ico">
211
+ <meta property="og:image" content="logo.png">
208
212
  <meta name="description" content="Nine Godot 4 games built with Spawn Point: platformers, a sword fighter, tower defense, a space shooter, a bubble shooter, a survivor, a farm. Play in your browser.">
209
213
  <meta property="og:title" content="Spawn Point demos: play Godot games in your browser">
210
214
  <meta property="og:description" content="A Mario-style platformer, a ninja rescue, a dinosaur-egg shooter, a survivor and an arena, all built from Spawn Point components.">
@@ -243,7 +247,7 @@ footer {{ color:var(--muted); font-size:13px; padding-bottom:40px }}
243
247
  </head>
244
248
  <body>
245
249
  <header>
246
- <h1>Spawn<span>Point</span> demos</h1>
250
+ <h1 class="brand"><img src="logo-icon-64.png" width="48" height="48" alt="" style="image-rendering:pixelated;vertical-align:middle;margin-right:10px">Spawn<span>Point</span> demos</h1>
247
251
  <p class="lede">Nine games, nine ways to play, all built by Spawn Point from small JSON game graphs and a
248
252
  library of tested Godot 4 components: game feel, cartoon or pixel art and collisions come for free. Click a card to play in
249
253
  your browser, no install needed.</p>
@@ -8,7 +8,7 @@
8
8
  var forced = location.search.indexOf("touch") >= 0; // ?touch shows the controls on a desktop (testing)
9
9
  if (!(coarse || forced || "ontouchstart" in window) || location.search.indexOf("shot") >= 0) return;
10
10
 
11
- var KEYS = {Space: " ", ShiftLeft: "Shift", KeyX: "x", KeyR: "r", KeyE: "e", Digit1: "1", Digit2: "2", Digit3: "3",
11
+ var KEYS = {Space: " ", ShiftLeft: "Shift", KeyX: "x", KeyR: "r", KeyE: "e", Digit1: "1", Digit2: "2", Digit3: "3", KeyP: "p", KeyN: "n", KeyM: "m",
12
12
  ArrowLeft: "ArrowLeft",
13
13
  ArrowRight: "ArrowRight", ArrowUp: "ArrowUp", ArrowDown: "ArrowDown"};
14
14
  var held = {};
@@ -18,7 +18,7 @@ from .manifest import ADDON_DIR
18
18
  RECORD_SCENE = "res://addons/spawn_point/tools/record.tscn"
19
19
 
20
20
 
21
- def record_frames(project: Path, out_dir: Path, seconds: float, fps: int, skip: float = 0.0) -> list[Path]:
21
+ def record_frames(project: Path, out_dir: Path, seconds: float, fps: int, skip: float = 0.0, focus: str = "") -> list[Path]:
22
22
  # Projects built before the recorder existed get the current tool copied in.
23
23
  tools = project / "addons" / "spawn_point" / "tools"
24
24
  for name in ("record.gd", "record.tscn"):
@@ -26,7 +26,7 @@ def record_frames(project: Path, out_dir: Path, seconds: float, fps: int, skip:
26
26
  step = max(1, round(60 / fps))
27
27
  total = int(seconds * 60)
28
28
  cmd = [godot.find_binary(), "--path", str(project), "--fixed-fps", "60", RECORD_SCENE,
29
- "--", str(out_dir), str(total), str(step), str(int(skip * 60))]
29
+ "--", str(out_dir), str(total), str(step), str(int(skip * 60)), focus]
30
30
  proc = subprocess.run(cmd, capture_output=True, text=True, timeout=(seconds + skip) * 20 + 60)
31
31
  frames = sorted(out_dir.glob("frame_*.png"))
32
32
  if not frames:
@@ -54,8 +54,27 @@ def make_gif(frames: list[Path], out: Path, fps: int, width: int, colors: int =
54
54
 
55
55
 
56
56
  def record_gif(project: Path, out: Path, seconds: float = 8.0, fps: int = 20, width: int = 640,
57
- skip: float = 0.0) -> Path:
58
- """`skip`: seconds of autopilot play before the clip starts (survivor games get busy later)."""
57
+ skip: float = 0.0, focus: str = "") -> Path:
58
+ """`skip`: seconds of autopilot play before the clip starts (survivor games get busy later). `focus` (farms):
59
+ what the autopilot does: "field", "animals", "fish" or "house"; empty for a bit of everything."""
59
60
  with tempfile.TemporaryDirectory() as tmp:
60
- frames = record_frames(project, Path(tmp), seconds, fps, skip)
61
+ frames = record_frames(project, Path(tmp), seconds, fps, skip, focus)
61
62
  return make_gif(frames, out, fps, width)
63
+
64
+
65
+ OVERVIEW_SCENE = "res://addons/spawn_point/tools/overview.tscn"
66
+
67
+
68
+ def overview(project: Path, out: Path, seconds: float = 20.0) -> Path:
69
+ """One picture of the whole map after `seconds` of autopilot play (crops grow, animals wander)."""
70
+ tools = project / "addons" / "spawn_point" / "tools"
71
+ for name in ("record.gd", "record.tscn", "overview.gd", "overview.tscn"):
72
+ shutil.copy2(ADDON_DIR / "tools" / name, tools / name)
73
+ out.parent.mkdir(parents=True, exist_ok=True)
74
+ out.unlink(missing_ok=True) # an old picture must not pass for a new one
75
+ cmd = [godot.find_binary(), "--path", str(project), "--fixed-fps", "60", OVERVIEW_SCENE, "--", str(out),
76
+ str(int(seconds * 60))]
77
+ proc = subprocess.run(cmd, capture_output=True, text=True, timeout=seconds * 20 + 60)
78
+ if not out.exists():
79
+ raise godot.GodotError("the overview produced no picture (is a display available?)", proc.stdout + proc.stderr)
80
+ return out
@@ -76,6 +76,9 @@ class Entity(_Model):
76
76
  components: dict[str, dict[str, Any]] = Field(default_factory=dict)
77
77
  juice: Union[Literal["none"], dict[str, Any], None] = None
78
78
  decor: bool = Field(default=False, description="scenery (trees, bushes, rocks): drawn behind everything, no collision")
79
+ # Footprint [width, height] in px: the entity stands on the bottom of its drawing (origin at its feet) and only
80
+ # this box at its base collides, so a tree's crown or a house's roof can be walked behind (with y_sort).
81
+ base: tuple[float, float] | None = None
79
82
 
80
83
 
81
84
  class Level(_Model):
@@ -99,6 +102,15 @@ class TileStyle(_Model):
99
102
  _color = field_validator("color", "top")(_check_color)
100
103
 
101
104
 
105
+ class ArtRequest(_Model):
106
+ """An extra picture drawn by the compiler for a component to use (res://sprites/art_<name>.png)."""
107
+ kind: Literal["crop", "crop_icon", "item_icon", "soil", "soil_wet"]
108
+ of: str = "" # the crop name ("Strawberry") or item ("egg", "milk", "wood", "stone", "fish", "hay")
109
+ color: str | None = None
110
+
111
+ _color = field_validator("color")(_check_color)
112
+
113
+
102
114
  class Settings(_Model):
103
115
  tile_size: int = Field(default=32, ge=8, le=128)
104
116
  viewport: tuple[int, int] = (960, 540)
@@ -117,6 +129,16 @@ class Settings(_Model):
117
129
  # colour, a theme name forces one, "flat" keeps the plain hills and checkered floor.
118
130
  scenery: Literal["auto", "flat", "night", "forest", "desert", "neon", "candy", "ocean", "lava", "snow", "space"] = "auto"
119
131
  zoom: float = Field(default=1.0, ge=0.5, le=4.0)
132
+ # A drawn ground for the whole map, one character per cell like the level map: "." grass, ":" dirt path,
133
+ # "~" water, "," tidy grass (fields), "_" sand. Used by farms; replaces the floor and scenery.
134
+ terrain: list[str] | None = None
135
+ season: Literal["spring", "autumn", "winter", "desert"] = "spring" # the terrain's colours
136
+ # Background music, composed at build time (see music.py): a season's tune, or none.
137
+ music: Literal["none", "spring", "autumn", "winter", "desert"] = "none"
138
+ # Draw entities lower on screen in front of the ones above them (top-down games with tall trees and houses).
139
+ y_sort: bool = False
140
+ # Extra pictures for components (crop growth stages, item icons, soil): name -> what to draw.
141
+ art: dict[str, ArtRequest] = Field(default_factory=dict)
120
142
 
121
143
  _bg = field_validator("background")(_check_color)
122
144
 
@@ -19,7 +19,7 @@ IMAGE = os.environ.get("VLLM_IMAGE", "vllm/vllm-openai:v0.10.2") # CUDA 12.8: N
19
19
  DEFAULT_MODEL = "smoky1496/SpawnPoint-Coder-7B-AWQ"
20
20
  MODEL = os.environ.get("SPAWNPOINT_MODEL", DEFAULT_MODEL)
21
21
  # This Spawn Point version speaks the v5 per-genre format: pin the weights that do, whatever the repo's main becomes.
22
- REVISION = os.environ.get("SPAWNPOINT_MODEL_REVISION") or ("v5.1-release" if MODEL == DEFAULT_MODEL else "")
22
+ REVISION = os.environ.get("SPAWNPOINT_MODEL_REVISION") or ("v5.2-release" if MODEL == DEFAULT_MODEL else "")
23
23
  SERVED = "SpawnPoint-Coder-7B"
24
24
  OLLAMA_MODEL = os.environ.get("SPAWNPOINT_OLLAMA_MODEL", "hf.co/smoky1496/SpawnPoint-Coder-7B-GGUF:Q4_K_M")
25
25
  OLLAMA_PORT = 11434