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.
- {spawnpoint_studio-0.3.3/compiler/spawnpoint_studio.egg-info → spawnpoint_studio-0.3.5}/PKG-INFO +60 -18
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/README.md +59 -17
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/analyze.py +31 -4
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/build.py +3 -1
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cli.py +29 -2
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/demo.py +9 -5
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/demo_touch.js +1 -1
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/gif.py +24 -5
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/graph.py +22 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/llm_server.py +1 -1
- spawnpoint_studio-0.3.5/compiler/spawnpoint/logo.py +167 -0
- spawnpoint_studio-0.3.5/compiler/spawnpoint/music.py +117 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/cartoon.py +4 -0
- spawnpoint_studio-0.3.5/compiler/spawnpoint/sprites/farm.py +1468 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/gallery.py +12 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/generate.py +15 -1
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/resolve.py +4 -2
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/assemble.py +213 -35
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/brief.py +9 -0
- spawnpoint_studio-0.3.5/compiler/spawnpoint/studio/farmgen.py +353 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/levelgen.py +0 -39
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/prompts.py +11 -1
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/webcheck.py +22 -6
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5/compiler/spawnpoint_studio.egg-info}/PKG-INFO +60 -18
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/SOURCES.txt +18 -0
- spawnpoint_studio-0.3.5/compiler/tests/test_farm.py +224 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_genres.py +3 -2
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_sprites.py +2 -1
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_studio.py +1 -1
- spawnpoint_studio-0.3.5/examples/sunny_farm.json +1043 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/animator_component.gd +15 -1
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_animal_component.gd +196 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_days_component.gd +186 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/farm_plot_component.gd +111 -5
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farm_save_component.gd +193 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/farmer_component.gd +445 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/fishing_spot_component.gd +103 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/game_menu_component.gd +157 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/gatherable_component.gd +70 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/market_component.gd +4 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/shop_component.gd +109 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/sleep_spot_component.gd +27 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/sprinkler_component.gd +58 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/tool_bench_component.gd +73 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/components/warp_component.gd +76 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/manifest.json +749 -23
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/game_state.gd +4 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/sfx.gd +30 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/build.gd +13 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/overview.gd +44 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/overview.tscn +6 -0
- spawnpoint_studio-0.3.5/godot/addons/spawn_point/tools/record.gd +435 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/pyproject.toml +1 -1
- spawnpoint_studio-0.3.3/examples/sunny_farm.json +0 -224
- spawnpoint_studio-0.3.3/godot/addons/spawn_point/components/farmer_component.gd +0 -158
- spawnpoint_studio-0.3.3/godot/addons/spawn_point/tools/record.gd +0 -233
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/LICENSE +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/MANIFEST.in +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/__init__.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/__init__.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/server.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/app.css +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/app.js +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/cockpit/static/index.html +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/diagnostics.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/expr.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/godot.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/level.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/manifest.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/__init__.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/report.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/runner.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/playtest/tuner.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/project.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/py.typed +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/rules.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sfx.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/__init__.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/ai.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/cartoon_monsters.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/chibi.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/contour.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/creatures.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/importer.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/items.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/monsters.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/motion.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/palettes.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/scenery.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/spriteset.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/sprites/tiles.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/__init__.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/creative.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/dataset.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/edits.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/genres.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/llm.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/orchestrator.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio/web.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint/studio_cli.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/dependency_links.txt +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/entry_points.txt +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/requires.txt +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/spawnpoint_studio.egg-info/top_level.txt +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/conftest.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_ai_sprites.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_analyze.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_cockpit.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_demo.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_e2e.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_expr.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_gif.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_godot_library.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_graph.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_level.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_live_llm.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_manifest.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_playtest.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_rules.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_sfx.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/compiler/tests/test_web.py +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/castle_defense.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/coin_hopper.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/dino_eggs.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/knight_quest.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/neon_arena.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/night_survivor.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/ninja_rescue.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/pixel_arena.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/pixel_hopper.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/examples/star_run.json +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/aim_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/base_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/bubble_board_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/chase_ai_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/collectible_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/crop_pest_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/experience_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/flight_path_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/gate_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/ground_patch_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/health_bar_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/health_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/hitbox_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/hurtbox_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/juice_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/level_up_menu_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/path_follower_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/patrol_ai_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/platformer_movement_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/player_input_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/projectile_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/shmup_ship_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/spawner_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/stomp_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/top_down_movement_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_brain_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_builder_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/tower_slot_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/trigger_zone_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/wave_spawner_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/weapon_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/components/xp_orb_component.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/camera_rig.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/cockpit.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/entity_core.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/fx.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/hud.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/level.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/sp.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/runtime/world.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/shaders/flash.gdshader +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/shaders/floor_grid.gdshader +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/build.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/capture.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/capture.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/dump_manifest.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/dump_manifest.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/playtest_nav.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/record.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/smoke.gd +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/godot/addons/spawn_point/tools/smoke.tscn +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/setup.cfg +0 -0
- {spawnpoint_studio-0.3.3 → spawnpoint_studio-0.3.5}/setup.py +0 -0
{spawnpoint_studio-0.3.3/compiler/spawnpoint_studio.egg-info → spawnpoint_studio-0.3.5}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spawnpoint-studio
|
|
3
|
-
Version: 0.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
|
[](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
|
|
32
34
|
[](https://leluong141996-dev.github.io/Spawn-Point/)
|
|
33
35
|
[](LICENSE)
|
|
36
|
+
[](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/
|
|
37
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
38
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
39
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
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>
|
|
45
|
-
|
|
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
|
|
50
|
-
|
|
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
|
|
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
|
-
|
|
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/
|
|
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,
|
|
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
|
[](https://huggingface.co/smoky1496/SpawnPoint-Coder-7B-AWQ)
|
|
8
10
|
[](https://leluong141996-dev.github.io/Spawn-Point/)
|
|
9
11
|
[](LICENSE)
|
|
12
|
+
[](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/
|
|
13
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
14
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
15
|
-
<img src="https://raw.githubusercontent.com/leluong141996-dev/Spawn-Point/main/docs/media/
|
|
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>
|
|
21
|
-
|
|
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
|
|
26
|
-
|
|
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
|
|
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
|
-
|
|
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/
|
|
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,
|
|
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
|
|
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
|
-
"
|
|
59
|
-
"Move: arrows / WASD |
|
|
60
|
-
{"pad": "dpad", "buttons": [["ACT", "Space"], ["SHOO", "KeyX"], ["
|
|
61
|
-
"tap": "
|
|
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.
|
|
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
|