Initial commit

This commit is contained in:
Haze Weathers 2025-08-06 10:26:28 -06:00
commit 3b96451047
71 changed files with 2302 additions and 0 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

21
LICENSE.txt Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Haze Weathers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1 @@
../../LICENSE.txt

View file

@ -0,0 +1,22 @@
@tool
class_name WBBasicInteractive
extends StaticBody2D
## Collision object that emits a signal when interacted with by a player character.
## Emitted when a player character interacts with this object.
signal interacted()
func _init() -> void:
for child in get_children():
if child is CollisionShape2D or child is CollisionPolygon2D:
return
var col_shape := CollisionShape2D.new()
col_shape.shape = RectangleShape2D.new()
col_shape.shape.size = Vector2(8.0, 8.0)
add_child(col_shape)
func interact() -> void:
interacted.emit()

View file

@ -0,0 +1 @@
uid://dkj06ucsoypda

View file

@ -0,0 +1,174 @@
@tool
@icon("character.svg")
class_name WBCharacter
extends CharacterBody2D
## A character that can be controlled by events and behaviors and moves on a grid.
## Emitted when the character begins moving.
signal move_started()
## Emitted when the character reaches its target position.
signal move_finished()
enum Dir {LEFT, RIGHT, UP, DOWN}
const DIR_VECTORS: Dictionary[Dir, Vector2] = {
Dir.LEFT: Vector2.LEFT,
Dir.RIGHT: Vector2.RIGHT,
Dir.UP: Vector2.UP,
Dir.DOWN: Vector2.DOWN,
}
const DIR_ANIM_SUFFIXES: Dictionary[Dir, StringName] = {
Dir.LEFT: &"_left",
Dir.RIGHT: &"_right",
Dir.UP: &"_up",
Dir.DOWN: &"_down",
}
## Size of the grid the character is restricted to.
@export var tile_size: float = 16.0
## Speed the character walks at.
@export var walk_speed: float = 4.0
## Speed the character runs at.
@export var run_speed: float = 8.0
## Direction the character is facing.
@export var facing: Dir = Dir.DOWN
## Animation library for the character. [br]
## At a minimum, the [code]idle_*[/code] animations are required. [br]
## The following animations are used by default behavior: [br]
## [code]idle_[left,right,up,down][/code] [br]
## [code]walk_[left,right,up,down][/code] [br]
## [code]run_[left,right,up,down][/code] [br]
## [code]run_*[/code] will fallback to [code]walk_*[/code],
## which will fallback to [code]idle_*[/code]. [br]
## Addition custom animations may be provided to play on demand.
@export var animations: SpriteFrames:
set(value):
animations = value
sprite.sprite_frames = animations
## Texture drawing offset of the animated sprite.
@export var sprite_offset: Vector2 = Vector2.ZERO:
set(value):
sprite_offset = value
sprite.offset = sprite_offset
## True when the character is moving.
var moving: bool = false
## Whether the character is running.
var running: bool = false
## Tile position of the character on the grid.
var tile_position: Vector2i:
get():
return pos_to_tile(global_position)
var sprite: AnimatedSprite2D
var _next_pos: Vector2
var _playing_custom_animation: bool = false
func _init() -> void:
sprite = AnimatedSprite2D.new()
sprite.sprite_frames = animations
add_child(sprite)
func _ready() -> void:
global_position = closest_tile_center(global_position)
for child in get_children():
if child is CollisionShape2D or child is CollisionPolygon2D:
return
var col_shape := CollisionShape2D.new()
col_shape.shape = RectangleShape2D.new()
col_shape.shape.size = Vector2(tile_size - 2.0, tile_size - 2.0)
add_child(col_shape)
func _physics_process(delta: float) -> void:
if moving:
var move_delta := (run_speed if running else walk_speed) * tile_size * delta
global_position = global_position.move_toward(_next_pos, move_delta)
if global_position == _next_pos:
moving = false
move_finished.emit()
func _process(delta: float) -> void:
if moving:
_playing_custom_animation = false
var anims: Array[StringName] = [
&"walk" + DIR_ANIM_SUFFIXES[facing],
&"idle" + DIR_ANIM_SUFFIXES[facing]
]
if running:
anims.push_front(&"run" + DIR_ANIM_SUFFIXES[facing])
_try_animations(anims)
elif not _playing_custom_animation:
_try_animations([&"idle" + DIR_ANIM_SUFFIXES[facing]])
## Makes the character move one tile in the given direction. [br]
## If [param ignore_collision] is true, the character will not perform collision checks.
func start_move(dir: Dir, ignore_collision: bool = false) -> bool:
if moving:
return false
facing = dir
_next_pos = global_position + DIR_VECTORS[dir] * tile_size
var col := move_and_collide(_next_pos - global_position, true)
if col and not ignore_collision:
return false
moving = true
move_started.emit()
return true
## Plays a given custom animation from the animation set. [br]
## If [param reset_after] is [constant true], the animation will return to
## the default idle animation after it finishes.
func play_custom_animation(anim: StringName, reset_after: bool = false) -> void:
_try_animations([anim])
_playing_custom_animation = true
if reset_after and not animations.get_animation_loop(anim):
await sprite.animation_finished
_playing_custom_animation = false
## Stops playing custom animation if one is currently playing.
func end_custom_animation() -> void:
_playing_custom_animation = false
## Returns the closest tile center position to a given position in global coordinates.
func closest_tile_center(pos: Vector2) -> Vector2:
var tile := pos - Vector2(tile_size, tile_size) * 0.5
tile = tile.snappedf(tile_size)
tile += Vector2(tile_size, tile_size) * 0.5
return tile
## Returns the tile coordinates of a given position in global coordinates.
func pos_to_tile(pos: Vector2) -> Vector2i:
return Vector2i((global_position / Vector2(tile_size, tile_size)).floor())
## Returns the center position of a given tile in global coordinates.
func tile_center_pos(tile: Vector2i) -> Vector2:
return (Vector2(tile) * Vector2(tile_size, tile_size)) + (Vector2(tile_size, tile_size) * 0.5)
func _try_animations(anims: Array[StringName]) -> void:
for anim in anims:
if animations.has_animation(anim):
sprite.play(anim)
return

View file

@ -0,0 +1 @@
uid://dx8lxwwkyrjin

View file

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="character.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="14.854978"
inkscape:cx="0.67317502"
inkscape:cy="10.434213"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="#8da5f3"
d="m 6.4922281,1 a 1,1 0 0 0 -1,1 v 3 a 1,1 0 0 0 1,1 h 1 v 0.99 a 1,1 0 0 0 -0.316,0.062 l -2.051,0.684 -0.684,-2.051 a 1.0000706,1.0000706 0 0 0 -1.898,0.631 l 1,3 a 1,1 0 0 0 1.265,0.633 l 1.684,-0.56 v 0.61 c 0,0.041 0.019,0.076 0.024,0.116 l -4.579,3.052 a 1.0001245,1.0001245 0 1 0 1.11,1.664 l 5.056,-3.37 1.495,2.986 a 1,1 0 0 0 1.2100009,0.502 l 3,-1 a 1,1 0 1 0 -0.632,-1.897 l -2.178,0.725 -0.975001,-1.951 A 0.981,0.981 0 0 0 10.492229,9.999 V 9 h 1.382999 l 0.722,1.448 a 1.0006409,1.0006409 0 1 0 1.790001,-0.895 l -1,-2 A 1,1 0 0 0 12.492229,7 H 9.4922281 V 6 h 1.0000009 a 1,1 0 0 0 1,-1 V 2 a 1,1 0 0 0 -1,-1 z m 0,2 h 1 v 2 h -1 z"
id="path1"
style="fill:#20c997" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ufpt8ejikj1j"
path="res://.godot/imported/character.svg-492c7305b4930c6092d7995fed4891a3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/characters/character.svg"
dest_files=["res://.godot/imported/character.svg-492c7305b4930c6092d7995fed4891a3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,44 @@
@tool
@icon("character_behavior.svg")
class_name WBCharacterBehavior
extends Node
## Controls/puppets a parent character.
## Whether the behavior is currently active.
@export var active: bool:
set(value):
var last_value := active
active = value
if active:
if not is_node_ready():
await ready
for child in get_parent().get_children():
if child != self and child is WBCharacterBehavior:
child.active = false
if active:
_activate()
else:
_deactivate()
## The character being controlled.
var character: WBCharacter:
get():
return get_parent() as WBCharacter
## Enables the behavior.
func enable() -> void:
active = true
## Disables the behavior.
func disable() -> void:
active = false
func _activate() -> void:
pass
func _deactivate() -> void:
pass

View file

@ -0,0 +1 @@
uid://cgunv5ngogsky

View file

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="character_behavior.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="14.854978"
inkscape:cx="0.67317502"
inkscape:cy="10.434213"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#20c997;stroke-width:2;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://lib4e4qnml8a"
path="res://.godot/imported/character_behavior.svg-d7dbdf997daf0ba87cdd58e5db5e61e1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/characters/character_behavior.svg"
dest_files=["res://.godot/imported/character_behavior.svg-d7dbdf997daf0ba87cdd58e5db5e61e1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,81 @@
@tool
@icon("path_behavior.svg")
class_name WBPathBehavior
extends WBCharacterBehavior
## A behavior that makes a character walk along a specified path,
## looping when they reach the end.
## List of points to walk to.
@export var points: Array[Vector2i]
## Whether the character should be running.
@export var run: bool = false
var _current_point: int
func _init() -> void:
if Engine.is_editor_hint():
add_child(DebugView.new(self))
func _activate() -> void:
_do_move()
func _do_move() -> void:
if not active:
return
if character.tile_position == points[_current_point]:
_current_point = posmod(_current_point + 1, points.size())
var point := points[_current_point]
if character.tile_position.x < point.x:
character.start_move(WBCharacter.Dir.RIGHT)
elif character.tile_position.x > point.x:
character.start_move(WBCharacter.Dir.LEFT)
elif character.tile_position.y < point.y:
character.start_move(WBCharacter.Dir.DOWN)
elif character.tile_position.y > point.y:
character.start_move(WBCharacter.Dir.UP)
if character.moving:
await character.move_finished
_do_move()
class DebugView extends Node2D:
var behavior: WBPathBehavior
func _init(p_behavior: WBPathBehavior) -> void:
behavior = p_behavior
func _process(delta: float) -> void:
if Engine.get_frames_drawn() % 60 == 0:
queue_redraw()
func _draw() -> void:
if not behavior.character:
return
var color := Color.MEDIUM_PURPLE
var width := -1.0
var selection := EditorInterface.get_selection()
if behavior in selection.get_selected_nodes():
color = Color.PURPLE
width = 2.0
var last_point := to_local(behavior.character.closest_tile_center(behavior.character.global_position))
for point in behavior.points + [behavior.points[0]]:
var current_point := to_local(behavior.character.tile_center_pos(point))
draw_line(last_point, Vector2(current_point.x, last_point.y), color, width)
draw_line(Vector2(current_point.x, last_point.y), current_point, color, width)
var arrow_dir := current_point.direction_to(Vector2(current_point.x, last_point.y))
if arrow_dir.is_zero_approx():
arrow_dir = current_point.direction_to(last_point)
draw_line(current_point, current_point + arrow_dir.rotated(deg_to_rad(45.0)) * 8.0, color, width)
draw_line(current_point, current_point + arrow_dir.rotated(deg_to_rad(-45.0)) * 8.0, color, width)
last_point = current_point

View file

@ -0,0 +1 @@
uid://deanlc8wbefgm

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="path_behavior.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="14.854978"
inkscape:cx="0.67317502"
inkscape:cy="10.434213"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#20c997;stroke-width:2;stroke-dasharray:none" />
<path
style="fill:none;fill-opacity:1;stroke:#20c997;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 4.2410027,11.511293 4.1736852,4.3083202 8.5493228,4.7122252 8.2127353,7.7415128 11.915198,8.2127353 11.242023,12.11715 Z"
id="path8" />
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d3los038dn424"
path="res://.godot/imported/path_behavior.svg-92b1066b81b0693c0689fa68366f00d0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/characters/path_behavior.svg"
dest_files=["res://.godot/imported/path_behavior.svg-92b1066b81b0693c0689fa68366f00d0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,98 @@
@tool
@icon("player_character.svg")
class_name WBPlayerCharacter
extends WBCharacter
## A character controlled directly by the player.
## Whether the character will react to player input.
@export var controllable: bool = true
## Time to wait after turning before the character will start moving.
@export var turn_walk_time: float = 0.25
## Collision mask for interactive objects.
## If a collision is detected, [method interact] will be called on the target object if it exists.
@export_flags_2d_physics var interact_mask: int:
set(value):
interact_mask = value
_interact_raycast.collision_mask = interact_mask
@export_group("Input Actions", "input_")
@export var input_left: StringName = &"ui_left"
@export var input_right: StringName = &"ui_right"
@export var input_up: StringName = &"ui_up"
@export var input_down: StringName = &"ui_down"
@export var input_interact: StringName = &"ui_accept"
@export var input_run: StringName = &"ui_cancel"
var _interact_raycast: RayCast2D
var _turn_cooldown: float = 0.0
func _init() -> void:
super._init()
move_finished.connect(_check_move_input)
_interact_raycast = RayCast2D.new()
_interact_raycast.enabled = false
_interact_raycast.collide_with_areas = true
_interact_raycast.hit_from_inside = true
_interact_raycast.add_exception(self)
add_child(_interact_raycast)
func _physics_process(delta: float) -> void:
if Engine.is_editor_hint():
return
_turn_cooldown -= delta
running = Input.is_action_pressed(input_run)
if not moving:
_check_move_input(true)
super._physics_process(delta)
## Enables player control of the character.
func enable_control() -> void:
controllable = true
## Disables player control of the character.
func disable_control() -> void:
controllable = false
func _check_move_input(check_turn_cooldown: bool = false) -> void:
if not controllable:
return
if Input.is_action_pressed(input_left):
_try_move(Dir.LEFT, check_turn_cooldown)
elif Input.is_action_pressed(input_right):
_try_move(Dir.RIGHT, check_turn_cooldown)
elif Input.is_action_pressed(input_up):
_try_move(Dir.UP, check_turn_cooldown)
elif Input.is_action_pressed(input_down):
_try_move(Dir.DOWN, check_turn_cooldown)
elif Input.is_action_just_pressed(input_interact):
_try_interact()
func _try_move(dir: Dir, check_turn_cooldown: bool) -> void:
if facing != dir:
_turn_cooldown = turn_walk_time
if running:
_turn_cooldown *= 0.5
facing = dir
if check_turn_cooldown and _turn_cooldown >= 0.0:
return
start_move(dir)
func _try_interact() -> void:
_interact_raycast.target_position = DIR_VECTORS[facing] * tile_size
_interact_raycast.force_raycast_update()
if _interact_raycast.is_colliding():
var interactive := _interact_raycast.get_collider()
if interactive.has_method(&"interact"):
interactive.interact()

View file

@ -0,0 +1 @@
uid://cbc7nngunyym7

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="player_character.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.753231"
inkscape:cx="4.5042892"
inkscape:cy="6.6787737"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="#8da5f3"
d="m 7.4922281,6.99 c -0.1079911,0.00346 -0.2147078,0.024398 -0.316,0.062 l -2.051,0.684 -0.684,-2.051 C 4.0205616,4.4196672 2.1225616,5.0506672 2.5432281,6.316 l 1,3 c 0.1744187,0.5242077 0.7408721,0.807658 1.265,0.633 l 1.684,-0.56 v 0.61 c 0,0.041 0.019,0.076 0.024,0.116 l -4.579,3.052 c -1.10956307,0.739954 4.369e-4,2.403954 1.11,1.664 l 5.056,-3.37 1.495,2.986 c 0.2223325,0.444998 0.7379489,0.658915 1.2100009,0.502 l 3,-1 c 1.302584,-0.402102 0.651473,-2.356463 -0.632,-1.897 l -2.178,0.725 -0.975001,-1.951 c 0.288394,-0.176434 0.465617,-0.488934 0.469001,-0.827 V 9 h 1.382999 l 0.722,1.448 c 0.596513,1.193792 2.386514,0.298792 1.790001,-0.895 l -1,-2 C 13.217804,7.2139484 12.871255,6.9998234 12.492229,7 H 9.4922281 Z"
id="path1"
style="fill:#20c997"
sodipodi:nodetypes="ccccccccsccccccccccccccccccc" />
<path
style="fill:#20c997;fill-opacity:1;stroke:none;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 8.7367679,7.0282444 7.843676,4.89259 5.1644006,4.0383283 7.843676,2.951086 9.1250687,0.46596095 9.78518,3.1064064 12.969247,3.8830079 9.6686898,4.8537599 9.7463498,3.1452364 7.882506,3.0287462 l 0.03883,1.7861836 1.7861837,0.07766 z"
id="path8" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cdwrfpa2xn5cf"
path="res://.godot/imported/player_character.svg-b26ca4ad6a1901b6ebacace37c911113.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/characters/player_character.svg"
dest_files=["res://.godot/imported/player_character.svg-b26ca4ad6a1901b6ebacace37c911113.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,78 @@
@tool
@icon("wander_behavior.svg")
class_name WBWanderBehavior
extends WBCharacterBehavior
## A behavior that makes a character randomly wander around within a specified area.
## Rectangle enclosing the tiles the character is allowed to move to.
@export var territory: Rect2i
## Minimum distance to travel in one "burst".
@export var min_distance: int
## Maximum distance to travel in one "burst".
@export var max_distance: int
## Minimum time to idle after finishing a "burst".
@export_custom(0, "suffix:s") var min_idle: float
## Maximum time to idle after finishing a "burst".
@export_custom(0, "suffix:s") var max_idle: float
## Whether the character should run.
@export var run: bool = false
func _init() -> void:
if Engine.is_editor_hint():
add_child(DebugView.new(self))
func _activate() -> void:
if character:
_do_move()
func _do_move() -> void:
if not active:
return
var remaining_distance: int = randi_range(min_distance, max_distance)
var dir: WBCharacter.Dir = WBCharacter.Dir.values().pick_random()
while remaining_distance > 0:
while not territory.has_point(character.tile_position + Vector2i(WBCharacter.DIR_VECTORS[dir])):
dir = WBCharacter.Dir.values().pick_random()
character.running = run
character.start_move(dir)
if character.moving:
await character.move_finished
remaining_distance -= 1
await create_tween().tween_interval(randf_range(min_idle, max_idle)).finished
_do_move()
class DebugView extends Node2D:
var behavior: WBWanderBehavior
func _init(p_behavior: WBWanderBehavior) -> void:
behavior = p_behavior
func _process(delta: float) -> void:
if Engine.get_frames_drawn() % 60 == 0:
queue_redraw()
func _draw() -> void:
if not behavior.character:
return
var position := to_local(Vector2(behavior.territory.position) * behavior.character.tile_size)
var size := Vector2(behavior.territory.size) * behavior.character.tile_size
var color := Color.MEDIUM_PURPLE
var width := -1.0
var selection := EditorInterface.get_selection()
if behavior in selection.get_selected_nodes():
color = Color.PURPLE
width = 2.0
draw_rect(
Rect2(position, size),
color, false, width
)

View file

@ -0,0 +1 @@
uid://xcfljtjwi1vt

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="wander_behavior.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="14.854978"
inkscape:cx="0.67317502"
inkscape:cy="10.434213"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#20c997;stroke-width:2;stroke-dasharray:none" />
<path
style="fill:#20c997;fill-opacity:1;stroke:#20c997;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 3.9276284,7.9330316 5.599787,7.0386211 5.5608995,8.8663295 Z"
id="path5"
sodipodi:nodetypes="cccc" />
<path
style="fill:#20c997;fill-opacity:1;stroke:#20c997;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 11.501205,7.9790821 9.8290464,8.8734926 9.8679344,7.0457842 Z"
id="path6"
sodipodi:nodetypes="cccc" />
<path
style="fill:#20c997;fill-opacity:1;stroke:#20c997;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 7.7568856,4.1887121 8.6512961,5.8608707 6.8235877,5.8219827 Z"
id="path7"
sodipodi:nodetypes="cccc" />
<path
style="fill:#20c997;fill-opacity:1;stroke:#20c997;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 7.5941729,11.762289 6.6997624,10.09013 8.5274708,10.129018 Z"
id="path8"
sodipodi:nodetypes="cccc" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dcb3i7xdowdte"
path="res://.godot/imported/wander_behavior.svg-cec028e106c64cd15d62b2fb10cf549b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/characters/wander_behavior.svg"
dest_files=["res://.godot/imported/wander_behavior.svg-cec028e106c64cd15d62b2fb10cf549b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,31 @@
@icon("character_animation_event.svg")
class_name WBCharacterAnimationEvent
extends WBEvent
## Event that makes a character play a specific animation.
## Character to animate.
@export var character: WBCharacter
## Animation to play.
@export var animation: StringName
## Number of times to let animation loop if the animation loops.
@export var loops: int = 1
func _perform() -> void:
if not character:
push_error("Target character does not exist.")
return
if not character.animations.has_animation(animation):
push_error("The specified animation does not exist in this character.")
return
character.play_custom_animation(animation)
if character.animations.get_animation_loop(animation):
var remaining_loops := loops
while remaining_loops > 0:
await character.sprite.animation_looped
remaining_loops -= 1
else:
await character.sprite.animation_finished
character.end_custom_animation()

View file

@ -0,0 +1 @@
uid://c4bjkninxu305

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="character_animation_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
fill="url(#a)"
d="M 12.816902,3.0999201 H 3.0167421 V 3.7999316 H 4.4167649 V 5.1999544 H 3.0167421 v 5.6000916 h 1.4000228 v 1.400023 H 3.0167421 V 12.90008 H 12.816902 V 12.200069 H 11.41688 v -1.400023 h 1.400022 V 5.1999544 H 11.41688 V 3.7999316 h 1.400022 z M 10.016857,3.7999316 V 5.1999544 H 8.6168334 V 3.7999316 Z m 0,7.0001144 v 1.400023 H 8.6168334 V 10.800046 Z M 7.2168106,3.7999316 V 5.1999544 H 5.8167878 V 3.7999316 Z m 0,7.0001144 v 1.400023 H 5.8167878 V 10.800046 Z M 6.5167991,6.6748784 a 0.52500856,0.52500856 0 0 1 0.787513,-0.4459073 l 2.1000343,1.3181214 a 0.52500856,0.52500856 0 0 1 0,0.9051148 L 7.3043121,9.7703293 A 0.52500856,0.52500856 0 0 1 6.5167991,9.324422 Z"
id="path4"
style="fill:#8da5f3;fill-opacity:1;stroke-width:0.700012" />
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ddeaoeqtcg5x2"
path="res://.godot/imported/character_animation_event.svg-d0fd25cb2ad4401cf873b25840865b53.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/character_animation_event.svg"
dest_files=["res://.godot/imported/character_animation_event.svg-d0fd25cb2ad4401cf873b25840865b53.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,12 @@
@icon("delay_event.svg")
class_name WBDelayEvent
extends WBEvent
## Event that waits for a given duration.
## Time to wait for.
@export_custom(0, "suffix:s") var delay: float
func _perform() -> void:
await create_tween().tween_interval(delay).finished

View file

@ -0,0 +1 @@
uid://bqapvnlskkprc

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="delay_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
fill="#e0e0e0"
d="m 4.8110802,3.5943837 a 0.62779194,0.62779194 0 0 0 -0.6277919,0.627792 c 0,0.9416879 0.6070748,1.6479538 1.1758543,2.2977185 C 5.8362645,7.0660732 6.248096,7.5513563 6.5362525,7.9889273 6.248096,8.4264983 5.8368922,8.913037 5.3591426,9.4592163 4.7903631,10.10898 4.1832883,10.813991 4.1832883,11.755679 a 0.62779194,0.62779194 0 0 0 0.6277919,0.627792 H 11.089 a 0.62779194,0.62779194 0 0 0 0.627792,-0.627792 c 0,-0.941688 -0.607075,-1.646699 -1.175855,-2.2964627 C 10.063815,8.913037 9.6519839,8.4264983 9.3638269,7.9889273 9.6519839,7.5513563 10.063188,7.0660732 10.540937,6.5198942 11.109717,5.8701295 11.716792,5.1638636 11.716792,4.2221757 A 0.62779194,0.62779194 0 0 0 11.089,3.5943837 Z M 10.092066,4.8499676 C 9.9426519,5.1261961 9.9005899,5.3459232 9.5967379,5.6924644 9.0668819,6.2976558 8.4051891,6.9304701 8.0159581,7.7076765 A 0.62779194,0.62779194 0 0 0 7.9500399,7.9889273 0.62779194,0.62779194 0 0 0 7.883494,7.7083043 C 7.4948907,6.9304701 6.833198,6.2976558 6.3033417,5.6924644 5.9994904,5.3452955 5.9574283,5.1268239 5.807386,4.8499676 Z"
id="path1-2"
style="stroke-width:0.627792" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://codl7c70plmp0"
path="res://.godot/imported/delay_event.svg-51be5be8e4173986beaba93125ff14e2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/delay_event.svg"
dest_files=["res://.godot/imported/delay_event.svg-51be5be8e4173986beaba93125ff14e2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,33 @@
@icon("event.svg")
class_name WBEvent
extends Node
## Basic event that does nothing and emits its signals.
## Emitted when the event starts performing.
signal event_started()
## Emitted when the event has finished performing.
signal event_finished()
## [constant true] when the event is currently active.
## It is an error to try to perform an event that is already running.
var running: bool = false
## Starts the event.
func perform() -> void:
if running:
push_error("Event may not be performed if it is already running.")
running = true
event_started.emit()
await _perform()
running = false
event_finished.emit()
func _perform() -> void:
pass

View file

@ -0,0 +1 @@
uid://drkkeoynpxpgd

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.31301"
id="rect4"
width="1.1482214"
height="1.1907481"
x="7.3398166"
y="10.89865" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.76085"
id="rect5"
width="0.64153773"
height="3.8329279"
x="7.5902767"
y="4.1139956" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://df7egmuwd6mtt"
path="res://.godot/imported/event.svg-94666083a457e4b1b83e2b5cf3cf906d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/event.svg"
dest_files=["res://.godot/imported/event.svg-94666083a457e4b1b83e2b5cf3cf906d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,37 @@
@icon("move_character_event.svg")
class_name WBMoveCharacterEvent
extends WBEvent
## Event that moves a character to the specified tile.
## Charcter to move.
@export var character: WBCharacter
## Tile position to move the target to.
@export var target_tile: Vector2i
## Whether the character should be running.
@export var run: bool = false
## Whether the character should move vertically or horizontally first.
@export var prefer_vertical: bool = false
func _perform() -> void:
while character.tile_position != target_tile:
if prefer_vertical:
if character.tile_position.y < target_tile.y:
character.start_move(WBCharacter.Dir.DOWN, true)
elif character.tile_position.y > target_tile.y:
character.start_move(WBCharacter.Dir.UP, true)
elif character.tile_position.x < target_tile.x:
character.start_move(WBCharacter.Dir.RIGHT, true)
elif character.tile_position.x > target_tile.x:
character.start_move(WBCharacter.Dir.LEFT, true)
else:
if character.tile_position.x < target_tile.x:
character.start_move(WBCharacter.Dir.RIGHT, true)
elif character.tile_position.x > target_tile.x:
character.start_move(WBCharacter.Dir.LEFT, true)
elif character.tile_position.y < target_tile.y:
character.start_move(WBCharacter.Dir.DOWN, true)
elif character.tile_position.y > target_tile.y:
character.start_move(WBCharacter.Dir.UP, true)
await character.move_finished

View file

@ -0,0 +1 @@
uid://tajefl5yoipy

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="move_character_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
style="fill:#8da5f3;fill-opacity:1;stroke:none;stroke-width:2;stroke-dasharray:none"
d="m 3.694304,12.560634 0.1555495,-8.1663567 6.6108595,0.077775 0.07777,-1.1666223 2.022146,2.5665691 -2.099921,2.0610326 0,-1.5943838 -5.1331379,-0.077775 -0.038887,6.2219851 z"
id="path5"
sodipodi:nodetypes="cccccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ckyw0hvg7jhij"
path="res://.godot/imported/move_character_event.svg-9eb1716c5e768c9b0d5289ef761908df.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/move_character_event.svg"
dest_files=["res://.godot/imported/move_character_event.svg-9eb1716c5e768c9b0d5289ef761908df.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,26 @@
@icon("parallel_event.svg")
class_name WBParallelEvent
extends WBEvent
## Event that starts all child events at the same time, then finishes once all have completed.
signal _children_finished()
var _children_running: int = 0
func _perform() -> void:
for child in get_children():
if child is WBEvent:
_start_child(child)
if _children_running > 0:
await _children_finished
func _start_child(event: WBEvent) -> void:
_children_running += 1
await event.perform()
_children_running -= 1
if _children_running <= 0:
_children_finished.emit()

View file

@ -0,0 +1 @@
uid://dcwk6e3ufl2rs

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="parallel_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:2.02785"
id="rect3"
width="0.54810518"
height="5.949976"
x="5.4226375"
y="4.9062467" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.9332"
id="rect5"
width="0.48720151"
height="6.083509"
x="10.030569"
y="4.7445955" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ckrac6a5h1sd4"
path="res://.godot/imported/parallel_event.svg-c258bd2568944bcb205b6d0f605db926.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/parallel_event.svg"
dest_files=["res://.godot/imported/parallel_event.svg-c258bd2568944bcb205b6d0f605db926.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,12 @@
@icon("sequence_event.svg")
class_name WBSequenceEvent
extends WBEvent
## Event that performs each child event in sequence, one after another.
func _perform() -> void:
event_started.emit()
for child in get_children():
if child is WBEvent:
await child.perform()
event_finished.emit()

View file

@ -0,0 +1 @@
uid://cghsjdjghxhn6

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="sequence_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.28162"
id="rect3"
width="1.1207687"
height="1.1622787"
x="3.9217882"
y="7.9282513" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.31301"
id="rect4"
width="1.1482214"
height="1.1907481"
x="7.4175916"
y="7.9043198" />
<rect
style="fill:#dd5498;stroke:#dd5498;stroke-width:1.28162"
id="rect5"
width="1.1207687"
height="1.1622787"
x="11.044965"
y="7.9186711" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bakm6fp22sxac"
path="res://.godot/imported/sequence_event.svg-1b2ebbf7d19a80d4622c19258498b900.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/sequence_event.svg"
dest_files=["res://.godot/imported/sequence_event.svg-1b2ebbf7d19a80d4622c19258498b900.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,17 @@
@icon("teleport_character_event.svg")
class_name WBTeleportCharacterEvent
extends WBEvent
## Event that teleports a character to the specified tile position.
## Character to teleport.
@export var character: WBCharacter
## Tile position to teleport the character to.
@export var target_tile: Vector2i
func _perform() -> void:
if not character:
push_error("Target character does not exist.")
return
character.global_position = character.tile_center_pos(target_tile)

View file

@ -0,0 +1 @@
uid://dco2ay8p6o615

View file

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="teleport_character_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
sodipodi:type="star"
style="fill:none;fill-opacity:1;stroke:#8da5f3;stroke-width:1.34623;stroke-dasharray:none;stroke-opacity:1"
id="path5"
inkscape:flatsided="false"
sodipodi:sides="5"
sodipodi:cx="4.8220387"
sodipodi:cy="5.0942507"
sodipodi:r1="5.4158311"
sodipodi:r2="2.7079153"
sodipodi:arg1="0.61190243"
sodipodi:arg2="1.240221"
inkscape:rounded="0"
inkscape:randomized="0"
d="M 9.2552034,8.2052435 5.7009935,7.655548 3.2332319,10.271791 2.6577122,6.7216708 -0.5930627,5.1831535 2.6054565,3.5387543 3.0641287,-0.02834426 5.616442,2.505481 9.1506919,1.8394101 7.5295891,5.0497994 Z"
inkscape:transform-center-x="0.37156418"
inkscape:transform-center-y="0.020029869"
transform="matrix(0.75679887,0,0,0.72909077,4.6005899,4.4238451)" />
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cpqqmbh3d5nev"
path="res://.godot/imported/teleport_character_event.svg-984335146dbb260f6d1052999d295a22.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/teleport_character_event.svg"
dest_files=["res://.godot/imported/teleport_character_event.svg-984335146dbb260f6d1052999d295a22.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,21 @@
@icon("wait_signal_event.svg")
class_name WBWaitSignalEvent
extends WBEvent
## Event that waits for a specified signal on a target node to be emitted.
## Node to await a signal of.
@export var target: Node
## Signal to await.
@export var signal_to_await: StringName = &""
func _perform() -> void:
if not target:
push_error("Target object is not specified.")
return
if not target.has_signal(signal_to_await):
push_error("Target does not have the specified signal.")
return
await Signal(target, signal_to_await)

View file

@ -0,0 +1 @@
uid://cqodqaf46ktes

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="wait_signal_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
fill="#ff5f5f"
d="m 3.5788288,4.711046 v 6.577908 H 4.8944104 7.5255736 V 9.9733724 H 4.8944104 V 6.0266276 H 7.5255736 V 4.711046 H 4.8944104 Z M 9.4989464,5.3688368 V 7.3422092 H 6.209992 V 8.6577908 H 9.4989464 V 10.631163 L 11.143423,9.3155816 12.7879,8 11.143423,6.6844184 Z"
id="path1-5"
style="stroke-width:0.657791" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ccury2hlmsf45"
path="res://.godot/imported/wait_signal_event.svg-d1b2d658af4493719cdf3a0f1a267c69.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/wait_signal_event.svg"
dest_files=["res://.godot/imported/wait_signal_event.svg-d1b2d658af4493719cdf3a0f1a267c69.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,27 @@
@icon("walk_character_event.svg")
class_name WBWalkCharacterEvent
extends WBEvent
## Event that makes a character walk a certain distance in the given direction.
## Character to move.
@export var character: WBCharacter
## Direction for the character to walk.
@export var direction: WBCharacter.Dir
## Number of tiles to move the character.
@export_custom(0, "suffix:tiles") var distance: int
## Whether the character should be running.
@export var run: bool = false
func _perform() -> void:
if not character:
push_error("Target character does not exist.")
return
character.running = run
var remaining_distance := distance
while remaining_distance > 0:
character.start_move(direction, true)
await character.move_finished
remaining_distance -= 1

View file

@ -0,0 +1 @@
uid://csxb817wahr5q

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="move_character_event.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="25.715264"
inkscape:cx="5.1720255"
inkscape:cy="9.488528"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="none"
stroke="#8da5f3"
stroke-linejoin="round"
stroke-width="2.28571"
d="M 14.857145,14.857148 H 1.1428572 V 1.1428572 H 14.857145 Z"
id="path1"
style="stroke:#dd5498;stroke-width:2;stroke-dasharray:none" />
<path
style="fill:#8da5f3;fill-opacity:1;stroke:none;stroke-width:2;stroke-dasharray:none"
d="m 3.6554165,9.6440776 -0.038887,-2.761006 5.1720255,-1e-7 0.038887,-2.0610327 3.577642,3.4998669 -3.4998673,3.4998663 -0.077775,-2.138807 z"
id="path5"
sodipodi:nodetypes="cccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dc8q0sv4w2lxc"
path="res://.godot/imported/walk_character_event.svg-dcf6bff1559ceda5cbf4918ee7e487a2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/walkabout/events/walk_character_event.svg"
dest_files=["res://.godot/imported/walk_character_event.svg-dcf6bff1559ceda5cbf4918ee7e487a2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

View file

@ -0,0 +1,7 @@
[plugin]
name="WalkAbout"
description="Overworld character movement and cutscenes system."
author="fogwaves"
version="0.1"
script="walkabout_plugin.gd"

View file

@ -0,0 +1,12 @@
@tool
extends EditorPlugin
func _enter_tree() -> void:
# Initialization of the plugin goes here.
pass
func _exit_tree() -> void:
# Clean-up of the plugin goes here.
pass

View file

@ -0,0 +1 @@
uid://bgk2xef0qnnhl

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

34
icon.png.import Normal file
View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dr7lkn2nxpjwl"
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.png"
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

71
icon.svg Normal file
View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
version="1.1"
id="svg1"
sodipodi:docname="icon.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
inkscape:export-filename="/home/fogwaves/godot/godot-walkabout/icon.png"
inkscape:export-xdpi="384"
inkscape:export-ydpi="384"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1">
<linearGradient
id="a"
x2="0"
y1="2"
y2="14"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(4)">
<stop
offset="0"
stop-color="#ff8dbc"
id="stop1" />
<stop
offset=".4"
stop-color="#7260ff"
id="stop2" />
<stop
offset=".6"
stop-color="#7260ff"
id="stop3" />
<stop
offset="1"
stop-color="#74c9ff"
id="stop4" />
</linearGradient>
</defs>
<sodipodi:namedview
id="namedview1"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#505050"
inkscape:zoom="10.102647"
inkscape:cx="-7.9187165"
inkscape:cy="6.4339572"
inkscape:window-width="1346"
inkscape:window-height="727"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" />
<path
fill="#8da5f3"
d="m 7.4922281,6.99 c -0.1079911,0.00346 -0.2147078,0.024398 -0.316,0.062 l -2.051,0.684 -0.684,-2.051 C 4.0205616,4.4196672 2.1225616,5.0506672 2.5432281,6.316 l 1,3 c 0.1744187,0.5242077 0.7408721,0.807658 1.265,0.633 l 1.684,-0.56 v 0.61 c 0,0.041 0.019,0.076 0.024,0.116 l -4.579,3.052 c -1.10956307,0.739954 4.369e-4,2.403954 1.11,1.664 l 5.056,-3.37 1.495,2.986 c 0.2223325,0.444998 0.7379489,0.658915 1.2100009,0.502 l 3,-1 c 1.302584,-0.402102 0.651473,-2.356463 -0.632,-1.897 l -2.178,0.725 -0.975001,-1.951 c 0.288394,-0.176434 0.465617,-0.488934 0.469001,-0.827 V 9 h 1.382999 l 0.722,1.448 c 0.596513,1.193792 2.386514,0.298792 1.790001,-0.895 l -1,-2 C 13.217804,7.2139484 12.871255,6.9998234 12.492229,7 H 9.4922281 Z"
id="path1"
style="fill:#20c997"
sodipodi:nodetypes="ccccccccsccccccccccccccccccc" />
<path
style="fill:#20c997;fill-opacity:1;stroke:none;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
d="M 8.7367679,7.0282444 7.843676,4.89259 5.1644006,4.0383283 7.843676,2.951086 9.1250687,0.46596095 9.78518,3.1064064 12.969247,3.8830079 9.6686898,4.8537599 9.7463498,3.1452364 7.882506,3.0287462 l 0.03883,1.7861836 1.7861837,0.07766 z"
id="path8" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

37
icon.svg.import Normal file
View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b43nfydexd88g"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

24
project.godot Normal file
View file

@ -0,0 +1,24 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Godot WalkAbout"
config/features=PackedStringArray("4.4", "GL Compatibility")
config/icon="res://icon.svg"
[editor_plugins]
enabled=PackedStringArray("res://addons/walkabout/plugin.cfg")
[rendering]
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"