spawnpoint-studio 0.3.2__tar.gz → 0.3.4__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 (181) hide show
  1. {spawnpoint_studio-0.3.2/compiler/spawnpoint_studio.egg-info → spawnpoint_studio-0.3.4}/PKG-INFO +63 -22
  2. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/README.md +62 -21
  3. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/analyze.py +31 -4
  4. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cli.py +27 -2
  5. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/demo.py +4 -4
  6. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/gif.py +24 -5
  7. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/graph.py +20 -0
  8. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/llm_server.py +1 -1
  9. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/cartoon.py +7 -0
  10. spawnpoint_studio-0.3.4/compiler/spawnpoint/sprites/cartoon_monsters.py +152 -0
  11. spawnpoint_studio-0.3.4/compiler/spawnpoint/sprites/farm.py +1430 -0
  12. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/gallery.py +53 -0
  13. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/generate.py +26 -2
  14. spawnpoint_studio-0.3.4/compiler/spawnpoint/sprites/monsters.py +220 -0
  15. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/resolve.py +4 -2
  16. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/assemble.py +208 -43
  17. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/brief.py +9 -0
  18. spawnpoint_studio-0.3.4/compiler/spawnpoint/studio/farmgen.py +347 -0
  19. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/levelgen.py +0 -39
  20. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/prompts.py +13 -2
  21. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/webcheck.py +22 -6
  22. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4/compiler/spawnpoint_studio.egg-info}/PKG-INFO +63 -22
  23. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint_studio.egg-info/SOURCES.txt +15 -0
  24. spawnpoint_studio-0.3.4/compiler/tests/test_farm.py +195 -0
  25. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_genres.py +3 -2
  26. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_sprites.py +23 -4
  27. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_studio.py +2 -1
  28. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/castle_defense.json +2 -1
  29. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/coin_hopper.json +3 -2
  30. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/dino_eggs.json +2 -1
  31. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/knight_quest.json +4 -2
  32. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/neon_arena.json +3 -2
  33. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/night_survivor.json +3 -2
  34. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/ninja_rescue.json +3 -2
  35. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/pixel_arena.json +3 -2
  36. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/pixel_hopper.json +3 -2
  37. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/examples/star_run.json +2 -1
  38. spawnpoint_studio-0.3.4/examples/sunny_farm.json +982 -0
  39. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/animator_component.gd +15 -1
  40. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/farm_animal_component.gd +196 -0
  41. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/farm_days_component.gd +123 -0
  42. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/farm_plot_component.gd +104 -5
  43. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/farm_save_component.gd +175 -0
  44. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/farmer_component.gd +425 -0
  45. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/fishing_spot_component.gd +103 -0
  46. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/gatherable_component.gd +70 -0
  47. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/market_component.gd +4 -0
  48. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/sleep_spot_component.gd +27 -0
  49. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/tool_bench_component.gd +73 -0
  50. spawnpoint_studio-0.3.4/godot/addons/spawn_point/components/warp_component.gd +76 -0
  51. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/manifest.json +566 -8
  52. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/game_state.gd +3 -0
  53. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/build.gd +13 -0
  54. spawnpoint_studio-0.3.4/godot/addons/spawn_point/tools/overview.gd +44 -0
  55. spawnpoint_studio-0.3.4/godot/addons/spawn_point/tools/overview.tscn +6 -0
  56. spawnpoint_studio-0.3.4/godot/addons/spawn_point/tools/record.gd +435 -0
  57. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/pyproject.toml +1 -1
  58. spawnpoint_studio-0.3.2/examples/sunny_farm.json +0 -223
  59. spawnpoint_studio-0.3.2/godot/addons/spawn_point/components/farmer_component.gd +0 -158
  60. spawnpoint_studio-0.3.2/godot/addons/spawn_point/tools/record.gd +0 -233
  61. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/LICENSE +0 -0
  62. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/MANIFEST.in +0 -0
  63. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/__init__.py +0 -0
  64. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/build.py +0 -0
  65. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cockpit/__init__.py +0 -0
  66. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cockpit/server.py +0 -0
  67. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cockpit/static/app.css +0 -0
  68. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cockpit/static/app.js +0 -0
  69. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/cockpit/static/index.html +0 -0
  70. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/demo_touch.js +0 -0
  71. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/diagnostics.py +0 -0
  72. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/expr.py +0 -0
  73. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/godot.py +0 -0
  74. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/level.py +0 -0
  75. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/manifest.py +0 -0
  76. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/playtest/__init__.py +0 -0
  77. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/playtest/report.py +0 -0
  78. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/playtest/runner.py +0 -0
  79. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/playtest/tuner.py +0 -0
  80. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/project.py +0 -0
  81. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/py.typed +0 -0
  82. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/rules.py +0 -0
  83. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sfx.py +0 -0
  84. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/__init__.py +0 -0
  85. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/ai.py +0 -0
  86. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/chibi.py +0 -0
  87. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/contour.py +0 -0
  88. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/creatures.py +0 -0
  89. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/importer.py +0 -0
  90. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/items.py +0 -0
  91. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/motion.py +0 -0
  92. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/palettes.py +0 -0
  93. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/scenery.py +0 -0
  94. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/spriteset.py +0 -0
  95. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/sprites/tiles.py +0 -0
  96. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/__init__.py +0 -0
  97. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/creative.py +0 -0
  98. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/dataset.py +0 -0
  99. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/edits.py +0 -0
  100. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/genres.py +0 -0
  101. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/llm.py +0 -0
  102. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/orchestrator.py +0 -0
  103. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio/web.py +0 -0
  104. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint/studio_cli.py +0 -0
  105. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint_studio.egg-info/dependency_links.txt +0 -0
  106. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint_studio.egg-info/entry_points.txt +0 -0
  107. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint_studio.egg-info/requires.txt +0 -0
  108. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/spawnpoint_studio.egg-info/top_level.txt +0 -0
  109. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/conftest.py +0 -0
  110. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_ai_sprites.py +0 -0
  111. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_analyze.py +0 -0
  112. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_cockpit.py +0 -0
  113. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_demo.py +0 -0
  114. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_e2e.py +0 -0
  115. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_expr.py +0 -0
  116. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_gif.py +0 -0
  117. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_godot_library.py +0 -0
  118. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_graph.py +0 -0
  119. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_level.py +0 -0
  120. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_live_llm.py +0 -0
  121. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_manifest.py +0 -0
  122. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_playtest.py +0 -0
  123. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_rules.py +0 -0
  124. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_sfx.py +0 -0
  125. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/compiler/tests/test_web.py +0 -0
  126. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/aim_component.gd +0 -0
  127. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/base_component.gd +0 -0
  128. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/bubble_board_component.gd +0 -0
  129. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/chase_ai_component.gd +0 -0
  130. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/collectible_component.gd +0 -0
  131. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/crop_pest_component.gd +0 -0
  132. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/experience_component.gd +0 -0
  133. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/flight_path_component.gd +0 -0
  134. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/gate_component.gd +0 -0
  135. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/ground_patch_component.gd +0 -0
  136. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/health_bar_component.gd +0 -0
  137. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/health_component.gd +0 -0
  138. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/hitbox_component.gd +0 -0
  139. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/hurtbox_component.gd +0 -0
  140. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/juice_component.gd +0 -0
  141. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/level_up_menu_component.gd +0 -0
  142. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/path_follower_component.gd +0 -0
  143. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/patrol_ai_component.gd +0 -0
  144. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/platformer_movement_component.gd +0 -0
  145. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/player_input_component.gd +0 -0
  146. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/projectile_component.gd +0 -0
  147. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/shmup_ship_component.gd +0 -0
  148. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/spawner_component.gd +0 -0
  149. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/stomp_component.gd +0 -0
  150. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/top_down_movement_component.gd +0 -0
  151. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/tower_brain_component.gd +0 -0
  152. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/tower_builder_component.gd +0 -0
  153. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/tower_slot_component.gd +0 -0
  154. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/trigger_zone_component.gd +0 -0
  155. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/wave_spawner_component.gd +0 -0
  156. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/weapon_component.gd +0 -0
  157. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/components/xp_orb_component.gd +0 -0
  158. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/camera_rig.gd +0 -0
  159. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/cockpit.gd +0 -0
  160. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/entity_core.gd +0 -0
  161. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/fx.gd +0 -0
  162. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/hud.gd +0 -0
  163. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/level.gd +0 -0
  164. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/sfx.gd +0 -0
  165. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/sp.gd +0 -0
  166. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/runtime/world.gd +0 -0
  167. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/shaders/flash.gdshader +0 -0
  168. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/shaders/floor_grid.gdshader +0 -0
  169. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/build.tscn +0 -0
  170. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/capture.gd +0 -0
  171. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/capture.tscn +0 -0
  172. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/dump_manifest.gd +0 -0
  173. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/dump_manifest.tscn +0 -0
  174. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/playtest.gd +0 -0
  175. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/playtest.tscn +0 -0
  176. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/playtest_nav.gd +0 -0
  177. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/record.tscn +0 -0
  178. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/smoke.gd +0 -0
  179. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/godot/addons/spawn_point/tools/smoke.tscn +0 -0
  180. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/setup.cfg +0 -0
  181. {spawnpoint_studio-0.3.2 → spawnpoint_studio-0.3.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spawnpoint-studio
3
- Version: 0.3.2
3
+ Version: 0.3.4
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
@@ -31,23 +31,22 @@ Dynamic: license-file
31
31
  [![Model](https://img.shields.io/badge/%F0%9F%A4%97%20model-SpawnPoint--Coder--7B-yellow)](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
32
32
  [![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
33
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
34
+ [![GitHub stars](https://img.shields.io/github/stars/leluong141996-dev/Spawn-Point?style=social)](https://github.com/leluong141996-dev/Spawn-Point/stargazers)
35
+
36
+ ⭐ **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
37
 
35
38
  <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 cartoon-style 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">
39
+ <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">
40
+ <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">
41
+ <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">
42
+ <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
43
  </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 cartoon or pixel art, collision traced from the sprites, juice on by default.
46
- Recorded with <code>spawnpoint gif</code> (autopilot).</sub></p>
44
+ <p align="center"><sub>A cozy farm made from one sentence: the field, the animals, fishing and the farmhouse inside.
45
+ 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
46
 
48
- <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 cartoon
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
47
+ <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
48
+ knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a cozy
49
+ island farm, an arena shooter and a side-scrolling space shooter. No install needed, and
51
50
  they work on phones too (touch controls).</p>
52
51
 
53
52
  Spawn Point is an open-source, autonomous game studio that runs on your own machine. Instead of asking an LLM to type
@@ -156,7 +155,7 @@ Only what you asked for changes, and the level layout is kept. Prompts can be in
156
155
  **The model.** [SpawnPoint-Coder-7B](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ) is a 7B model
157
156
  fine-tuned to generate Godot 4 games through this pipeline: it writes the game design, tweaks and entity
158
157
  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
158
+ 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
159
  Docker and an NVIDIA GPU are present, otherwise the [GGUF build](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-GGUF)
161
160
  (Q4_K_M, ~4.7 GB) in Ollama. Force one with `--backend vllm|ollama`.
162
161
 
@@ -167,12 +166,53 @@ Web builds need the Godot **web export templates** (Editor → Manage Export Tem
167
166
  `web_*.zip` from the official `.tpz` into `~/.local/share/godot/export_templates/<version>/`);
168
167
  use `--no-web` to skip and play natively with `spawnpoint run`.
169
168
 
169
+ ## A cozy farm from one sentence
170
+
171
+ <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>
172
+
173
+ Ask for a farming game (`spawnpoint create "a cozy farming game with strawberries and pumpkins"`) and
174
+ 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
175
+ coop, a pond, a shipping bin, and woods around the edge, on an island (water all round, cliffs to the south; an
176
+ 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,
177
+ water with lily pads and reeds, buildings, fences, four kinds of tree, chickens and cows, a farmer who walks in four
178
+ directions, and crops with five growth stages (strawberries, carrots, potatoes, pumpkins, corn, wheat, cabbages...,
179
+ picked from the crop's name).
180
+
181
+ 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
182
+ at night; sleep in the farmhouse bed (or drop off in the fields at midnight) and watered crops grow overnight. Earn the
183
+ target before the season ends. What you do there: buy seeds (they cost money), till the grass with the hoe, plant,
184
+ water and harvest; feed the hens and the cow, then collect eggs and milk (chicks grow into hens); fish from the pond's
185
+ shore (cast, wait for the bite, reel in on the "!"); chop trees and break rocks for wood and stone; carry it all to the
186
+ shipping bin, while crows, foxes, rabbits or mice go for your crops. Step through the farmhouse door for a cozy room
187
+ inside (bed, fireplace, table, rug). Maps vary: the house on either side, the field and the pen swapping places, the
188
+ pond moving around. The workbench by the house sells tool upgrades (a watering can and a hoe that work a
189
+ 3x3 patch, a bigger basket, a sharper axe, a better rod), and the farm saves itself: close the game and it carries on
190
+ where you left it (a won or lost season, or R, starts a fresh one). On a phone, ACT does all of it and a tap on a seed in
191
+ the bar picks it. The
192
+ hotbar shows your seeds and basket. You walk behind trees and the house (the scene is depth-sorted), and only an
193
+ object's footprint blocks you. `spawnpoint overview <project>` saves a picture of the whole map after a short autopilot
194
+ run, like the one above.
195
+
196
+ <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>
197
+
198
+ 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
199
+ farm is winter (snow, a frozen pond, snowy pines and bare trees, and crops grow slower), a desert farm has sand, palms
200
+ and cacti (and the soil dries faster), an autumn farm is orange with maples, the rest is spring.
201
+
202
+ <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>
203
+ <p align="center">
204
+ <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">
205
+ <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">
206
+ <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">
207
+ </p>
208
+
170
209
  ## Sprites: generated or your own
171
210
 
172
- Layer 2 replaces placeholder shapes with **procedural sprites** — no assets, no GPU — in one of two art styles:
173
- **pixel art** (the default) or **cartoon** (`"art_style": "cartoon"` in the graph settings, or "cartoon style" in
174
- the prompt): smooth shaded sprites with a sticker outline, rounded tiles, and a parallax sky with hills, clouds and
175
- trees. The
211
+ 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.)
212
+
213
+ 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.
214
+
215
+ The
176
216
  kind follows the entity (`Goblin` → humanoid, `FireBat` → flyer, `LaserBot` → robot, `Crystal` → gem…)
177
217
  and details follow the name (`Ninja` → mask, `Fox` → ears and tail, `Spider` → legs, a sword-wielder holds a sword).
178
218
  Every sprite has idle / run / jump / fall / hurt animations driven automatically by an `Animator` component, plus
@@ -204,7 +244,8 @@ spawnpoint sprites import hero.png --grid 32x32 --anim idle=0-3 --anim run=4-9
204
244
  spawnpoint sprites import sheet.png --rows idle,run,jump # auto-sliced by transparent gutters
205
245
  spawnpoint sprites import kenney_frames/ # idle_0.png, walk_1.png, ...
206
246
  spawnpoint sprites preview assets/sprites/Knight.sprite.json # contact sheet + collision outline
207
- spawnpoint sprites gallery --style cartoon -o gallery.png # every kind on one sheet, for review
247
+ spawnpoint sprites gallery --style fine -o gallery.png # every kind on one sheet, for review
248
+ spawnpoint sprites parade --set monsters -o monsters.gif # an animated sheet of characters, monsters or items
208
249
  ```
209
250
 
210
251
  Names pick the art: `Knight` gets a helmet and shield, `SkeletonArcher` a skull and a bow (and shoots
@@ -214,7 +255,7 @@ match the palette, drawn behind everything and without collision.
214
255
  Record a clip of any built game to share it (a window opens for a few seconds; autopilot plays):
215
256
 
216
257
  ```bash
217
- spawnpoint gif out/pixel-hopper -o demo.gif --seconds 8 --fps 20 --width 640
258
+ spawnpoint gif out/sunny-farm -o demo.gif --seconds 10 --fps 10 --focus fish
218
259
  ```
219
260
 
220
261
  **AI art (optional plug-in).** Point Spawn Point at an image model and layer 2 asks it for the look of
@@ -366,7 +407,7 @@ headless smoke test (spawn, scripted input, crash detection) and report `E_RUNTI
366
407
  | Game modes | `BubbleBoard` (a complete bubble shooter: bank shots, colour pops, falling clusters, a descending ceiling) |
367
408
  | 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) |
368
409
  | 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) |
369
- | 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) |
410
+ | 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), `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) |
370
411
  | Feel | `Juice` — attached to every entity unless `"juice": "none"` |
371
412
 
372
413
  Runtime autoloads: `GameState` (score, lives, variables, win/lose), `World` (spawning, rule
@@ -7,23 +7,22 @@
7
7
  [![Model](https://img.shields.io/badge/%F0%9F%A4%97%20model-SpawnPoint--Coder--7B-yellow)](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
8
8
  [![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
9
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
10
+ [![GitHub stars](https://img.shields.io/github/stars/leluong141996-dev/Spawn-Point?style=social)](https://github.com/leluong141996-dev/Spawn-Point/stargazers)
11
+
12
+ ⭐ **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
13
 
11
14
  <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 cartoon-style 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">
15
+ <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">
16
+ <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">
17
+ <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">
18
+ <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
19
  </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 cartoon or pixel art, collision traced from the sprites, juice on by default.
22
- Recorded with <code>spawnpoint gif</code> (autopilot).</sub></p>
20
+ <p align="center"><sub>A cozy farm made from one sentence: the field, the animals, fishing and the farmhouse inside.
21
+ 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
22
 
24
- <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 cartoon
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
23
+ <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
24
+ knight with a sword, tower defense, a ninja rescue, a dinosaur-egg bubble shooter, a survivor with level-ups, a cozy
25
+ island farm, an arena shooter and a side-scrolling space shooter. No install needed, and
27
26
  they work on phones too (touch controls).</p>
28
27
 
29
28
  Spawn Point is an open-source, autonomous game studio that runs on your own machine. Instead of asking an LLM to type
@@ -132,7 +131,7 @@ Only what you asked for changes, and the level layout is kept. Prompts can be in
132
131
  **The model.** [SpawnPoint-Coder-7B](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ) is a 7B model
133
132
  fine-tuned to generate Godot 4 games through this pipeline: it writes the game design, tweaks and entity
134
133
  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
134
+ 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
135
  Docker and an NVIDIA GPU are present, otherwise the [GGUF build](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-GGUF)
137
136
  (Q4_K_M, ~4.7 GB) in Ollama. Force one with `--backend vllm|ollama`.
138
137
 
@@ -143,12 +142,53 @@ Web builds need the Godot **web export templates** (Editor → Manage Export Tem
143
142
  `web_*.zip` from the official `.tpz` into `~/.local/share/godot/export_templates/<version>/`);
144
143
  use `--no-web` to skip and play natively with `spawnpoint run`.
145
144
 
145
+ ## A cozy farm from one sentence
146
+
147
+ <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>
148
+
149
+ Ask for a farming game (`spawnpoint create "a cozy farming game with strawberries and pumpkins"`) and
150
+ 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
151
+ coop, a pond, a shipping bin, and woods around the edge, on an island (water all round, cliffs to the south; an
152
+ 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,
153
+ water with lily pads and reeds, buildings, fences, four kinds of tree, chickens and cows, a farmer who walks in four
154
+ directions, and crops with five growth stages (strawberries, carrots, potatoes, pumpkins, corn, wheat, cabbages...,
155
+ picked from the crop's name).
156
+
157
+ 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
158
+ at night; sleep in the farmhouse bed (or drop off in the fields at midnight) and watered crops grow overnight. Earn the
159
+ target before the season ends. What you do there: buy seeds (they cost money), till the grass with the hoe, plant,
160
+ water and harvest; feed the hens and the cow, then collect eggs and milk (chicks grow into hens); fish from the pond's
161
+ shore (cast, wait for the bite, reel in on the "!"); chop trees and break rocks for wood and stone; carry it all to the
162
+ shipping bin, while crows, foxes, rabbits or mice go for your crops. Step through the farmhouse door for a cozy room
163
+ inside (bed, fireplace, table, rug). Maps vary: the house on either side, the field and the pen swapping places, the
164
+ pond moving around. The workbench by the house sells tool upgrades (a watering can and a hoe that work a
165
+ 3x3 patch, a bigger basket, a sharper axe, a better rod), and the farm saves itself: close the game and it carries on
166
+ where you left it (a won or lost season, or R, starts a fresh one). On a phone, ACT does all of it and a tap on a seed in
167
+ the bar picks it. The
168
+ hotbar shows your seeds and basket. You walk behind trees and the house (the scene is depth-sorted), and only an
169
+ object's footprint blocks you. `spawnpoint overview <project>` saves a picture of the whole map after a short autopilot
170
+ run, like the one above.
171
+
172
+ <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>
173
+
174
+ 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
175
+ farm is winter (snow, a frozen pond, snowy pines and bare trees, and crops grow slower), a desert farm has sand, palms
176
+ and cacti (and the soil dries faster), an autumn farm is orange with maples, the rest is spring.
177
+
178
+ <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>
179
+ <p align="center">
180
+ <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">
181
+ <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">
182
+ <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">
183
+ </p>
184
+
146
185
  ## Sprites: generated or your own
147
186
 
148
- Layer 2 replaces placeholder shapes with **procedural sprites** — no assets, no GPU — in one of two art styles:
149
- **pixel art** (the default) or **cartoon** (`"art_style": "cartoon"` in the graph settings, or "cartoon style" in
150
- the prompt): smooth shaded sprites with a sticker outline, rounded tiles, and a parallax sky with hills, clouds and
151
- trees. The
187
+ 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.)
188
+
189
+ 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.
190
+
191
+ The
152
192
  kind follows the entity (`Goblin` → humanoid, `FireBat` → flyer, `LaserBot` → robot, `Crystal` → gem…)
153
193
  and details follow the name (`Ninja` → mask, `Fox` → ears and tail, `Spider` → legs, a sword-wielder holds a sword).
154
194
  Every sprite has idle / run / jump / fall / hurt animations driven automatically by an `Animator` component, plus
@@ -180,7 +220,8 @@ spawnpoint sprites import hero.png --grid 32x32 --anim idle=0-3 --anim run=4-9
180
220
  spawnpoint sprites import sheet.png --rows idle,run,jump # auto-sliced by transparent gutters
181
221
  spawnpoint sprites import kenney_frames/ # idle_0.png, walk_1.png, ...
182
222
  spawnpoint sprites preview assets/sprites/Knight.sprite.json # contact sheet + collision outline
183
- spawnpoint sprites gallery --style cartoon -o gallery.png # every kind on one sheet, for review
223
+ spawnpoint sprites gallery --style fine -o gallery.png # every kind on one sheet, for review
224
+ spawnpoint sprites parade --set monsters -o monsters.gif # an animated sheet of characters, monsters or items
184
225
  ```
185
226
 
186
227
  Names pick the art: `Knight` gets a helmet and shield, `SkeletonArcher` a skull and a bow (and shoots
@@ -190,7 +231,7 @@ match the palette, drawn behind everything and without collision.
190
231
  Record a clip of any built game to share it (a window opens for a few seconds; autopilot plays):
191
232
 
192
233
  ```bash
193
- spawnpoint gif out/pixel-hopper -o demo.gif --seconds 8 --fps 20 --width 640
234
+ spawnpoint gif out/sunny-farm -o demo.gif --seconds 10 --fps 10 --focus fish
194
235
  ```
195
236
 
196
237
  **AI art (optional plug-in).** Point Spawn Point at an image model and layer 2 asks it for the look of
@@ -342,7 +383,7 @@ headless smoke test (spawn, scripted input, crash detection) and report `E_RUNTI
342
383
  | Game modes | `BubbleBoard` (a complete bubble shooter: bank shots, colour pops, falling clusters, a descending ceiling) |
343
384
  | 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) |
344
385
  | 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) |
345
- | 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) |
386
+ | 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), `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) |
346
387
  | Feel | `Juice` — attached to every entity unless `"juice": "none"` |
347
388
 
348
389
  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")
@@ -94,6 +94,13 @@ 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
+ ov = sub.add_parser("overview", help="save one picture of a built project's whole map (needs a display)")
101
+ ov.add_argument("project", type=Path)
102
+ ov.add_argument("-o", "--out", type=Path, help="output file (default: <project>/overview.png)")
103
+ ov.add_argument("--seconds", type=float, default=20.0, help="seconds of autopilot play first")
97
104
 
98
105
  sp = sub.add_parser("sprites", help="import, generate or preview sprites")
99
106
  sps = sp.add_subparsers(dest="sprites_cmd", required=True)
@@ -124,6 +131,9 @@ def main(argv: list[str] | None = None) -> int:
124
131
  sga = sps.add_parser("gallery", help="render one contact sheet of every procedural kind, for review")
125
132
  sga.add_argument("--style", choices=["pixel", "fine", "cartoon"], default="fine")
126
133
  sga.add_argument("-o", "--out", type=Path, default=Path("sprite-gallery.png"))
134
+ spa = sps.add_parser("parade", help="render an animated sheet (GIF) of characters, monsters or items")
135
+ spa.add_argument("--set", dest="which", choices=["heroes", "monsters", "items"], default="heroes")
136
+ spa.add_argument("-o", "--out", type=Path, default=Path("sprite-parade.gif"))
127
137
 
128
138
  ds = sub.add_parser("dataset", help="recorded fine-tuning data")
129
139
  ds.add_argument("action", choices=["stats", "path"])
@@ -140,7 +150,7 @@ def main(argv: list[str] | None = None) -> int:
140
150
  return {"validate": _validate, "build": _build, "run": _run, "components": _components,
141
151
  "manifest": _manifest, "create": studio_cli.create, "tweak": studio_cli.tweak,
142
152
  "serve": studio_cli.serve, "dataset": studio_cli.dataset, "playtest": studio_cli.playtest, "studio": studio_cli.studio,
143
- "sprites": _sprites, "gif": _gif, "llm": _llm, "examples": _examples,
153
+ "sprites": _sprites, "gif": _gif, "overview": _overview, "llm": _llm, "examples": _examples,
144
154
  "demo": _demo}[args.cmd](args)
145
155
  except godot.GodotError as e:
146
156
  print(f"error: {e}", file=sys.stderr)
@@ -249,11 +259,20 @@ def _gif(args) -> int:
249
259
  from .gif import record_gif
250
260
 
251
261
  out = args.out or args.project / "demo.gif"
252
- path = record_gif(args.project.resolve(), out.resolve(), args.seconds, args.fps, args.width, args.skip)
262
+ path = record_gif(args.project.resolve(), out.resolve(), args.seconds, args.fps, args.width, args.skip, args.focus)
253
263
  print(f"Wrote {out} ({path.stat().st_size / 1e6:.1f} MB)")
254
264
  return 0
255
265
 
256
266
 
267
+ def _overview(args) -> int:
268
+ from .gif import overview
269
+
270
+ out = args.out or args.project / "overview.png"
271
+ overview(args.project.resolve(), out.resolve(), args.seconds)
272
+ print(f"Wrote {out}")
273
+ return 0
274
+
275
+
257
276
  def _demo(args) -> int:
258
277
  from .demo import build_site
259
278
 
@@ -275,6 +294,12 @@ def _sprites(args) -> int:
275
294
  for k, spec in gen.KINDS.items():
276
295
  print(f"{k:<8} {spec.size[0]}x{spec.size[1]} px animations: {', '.join(spec.anims)}")
277
296
  return 0
297
+ if args.sprites_cmd == "parade":
298
+ from .sprites.gallery import parade
299
+ frames = parade(args.which)
300
+ frames[0].save(args.out, save_all=True, append_images=frames[1:], duration=100, loop=0, optimize=True)
301
+ print(f"Wrote {args.out}")
302
+ return 0
278
303
  if args.sprites_cmd == "gallery":
279
304
  from .sprites.gallery import gallery
280
305
  gallery(args.style).save(args.out)
@@ -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, and sell it all at the shipping bin. Your farm is saved as you play.",
59
+ "Move: arrows / WASD | Till, plant, water, harvest, feed, fish, chop, go in, sleep: Space / E | Seed: 1 / 2 / 3 or click it | Shoo crows: X | Restart: R",
60
+ {"pad": "dpad", "buttons": [["ACT", "Space"], ["SHOO", "KeyX"]],
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",
@@ -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,14 @@ 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
+ # Draw entities lower on screen in front of the ones above them (top-down games with tall trees and houses).
137
+ y_sort: bool = False
138
+ # Extra pictures for components (crop growth stages, item icons, soil): name -> what to draw.
139
+ art: dict[str, ArtRequest] = Field(default_factory=dict)
120
140
 
121
141
  _bg = field_validator("background")(_check_color)
122
142
 
@@ -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
@@ -972,6 +972,9 @@ PAINTERS = {"hero": draw_hero, "slime": draw_blob, "hopper": draw_blob, "bug": d
972
972
  "beast": draw_beast, "spider": draw_spider, "dragon": draw_dragon, "ghost": draw_ghost, "snake": draw_snake,
973
973
  "key": draw_key, "potion": draw_potion, "scroll": draw_scroll, "bomb": draw_bomb, "chest": draw_chest,
974
974
  "arrow": draw_arrow, "tree": draw_tree, "bush": draw_bush, "rock": draw_rock}
975
+ from . import cartoon_monsters # noqa: E402 (needs Painter and the helpers above)
976
+
977
+ PAINTERS.update(cartoon_monsters.PAINTERS)
975
978
  OUTLINE = {"bullet": 0.8, "slash": 0.8, "coin": 1.0, "gem": 1.0, "star": 1.1, "heart": 1.1, "spikes": 1.0, "orb": 1.0,
976
979
  "key": 1.0, "potion": 1.0, "scroll": 1.0, "bomb": 1.0, "arrow": 0.8}
977
980
 
@@ -979,6 +982,10 @@ OUTLINE = {"bullet": 0.8, "slash": 0.8, "coin": 1.0, "gem": 1.0, "star": 1.1, "h
979
982
  def generate_cartoon(name: str, kind: str, color: str, features: list[str] | None = None, seed: int = 0) -> SpriteSet:
980
983
  if kind not in KINDS:
981
984
  raise ValueError(f"unknown sprite kind '{kind}'")
985
+ from . import farm
986
+ if kind in farm.SPRITES: # the farm set is pixel art only
987
+ from .generate import generate
988
+ return generate(name, kind, color, features, seed)
982
989
  spec = KINDS[kind]
983
990
  feats = list(features) if features is not None else features_for(name)
984
991
  rng_seed = zlib.crc32(f"{name}:{kind}:{seed}".encode())