godotartzones ·

Building Zone 00 — Le Réveil

Zone 00 is called Le Réveil — The Awakening. It’s where Hibiki opens his eyes and the world begins.

Building it took longer than expected. Not because of the code, but because of the image.

The wrong tool, then the right choice

My first instinct was to build backgrounds the way classic RPGs do it: tiling sprites, parallax layers, depth through movement. I spent two weeks building that system — ParallaxBackground, DecorElement nodes, layers of grass and fog and light.

It worked. It also felt completely wrong.

The game is meant to feel like a Studio Ghibli film — one coherent painted world, not a collage of assembled assets. Parallax layers can approximate that feeling, but they never quite get there. You always see the seams.

So I started over.

Finding the visual soul

The new approach: one illustration per zone, painted, full-scene. Each is integrated as a static Sprite2D in Godot — one image, one world.

The visual brief for Zone 00 was intentionally loose:

A misty forest clearing at dawn. A stone pedestal in the center. An ancient oak tree to the left, roots visible. A mossy stone archway portal on the right. Soft morning light, watercolor texture. Portrait orientation.

The result surprised me. The image had the right mood — something between Nausicaä and Princess Mononoke, soft and ancient and full of implied narrative. The oak tree canopy fills the top third. The clearing opens below it, pedestal centered. The archway sits right of frame, half-shrouded in mist.

Once the aesthetic was locked for Zone 00, I carried it forward as the visual reference for all future zones.

Portrait orientation — a choice that broke things

Zone 00 is a vertical space. The player starts at the top (the oak tree, the awakening) and moves downward through the clearing, toward a portal, toward whatever comes next.

This meant the illustration had to be portrait: 816×1456 pixels. At Godot’s 1280×720 viewport, that scales to 1280×2284 — a tall scrollable world.

This created a cascade of problems.

The old parallax system assumed landscape. The camera limits were calculated from layer sizes. The boundary collision shapes were hand-placed estimates. Everything needed rethinking.

BaseZone — the clean solution

I wrote base_zone.gd, a base class that every zone scene now extends:

extends Node2D
class_name BaseZone

@export var background: Sprite2D

func _ready() -> void:
    _setup_camera_limits()
    _setup_boundary_walls()

func _setup_camera_limits() -> void:
    var tex = background.texture
    var size = tex.get_size() * background.scale
    var half = size / 2.0
    # Camera limits from image bounds
    var cam = get_viewport().get_camera_2d()
    cam.limit_left   = int(-half.x)
    cam.limit_top    = int(-half.y)
    cam.limit_right  = int(half.x)
    cam.limit_bottom = int(half.y)

It reads the illustration’s texture size, applies the node’s scale, and sets the camera limits automatically. No more hardcoded values. Zone 01, when I add it, will just extend BaseZone and call super._ready().

The boundary walls are four invisible StaticBody2D shapes — one per edge — generated from the same image bounds. Hibiki can’t walk off the canvas.

The intro camera pan

Zone 00 needed something the others don’t: an opening cinematic.

When Hibiki first arrives, the camera starts at the top of the image — among the oak branches, before the clearing is visible. Then it slowly pans down, revealing the world.

I implemented this with a second Camera2D node (IntroCam) and a Tween:

func _start_intro() -> void:
    intro_cam.make_current()
    var tween = create_tween()
    tween.set_trans(Tween.TRANS_SINE)
    tween.set_ease(Tween.EASE_IN_OUT)
    tween.tween_property(intro_cam, "position:y", INTRO_CAM_END_Y, 4.5)
    tween.tween_callback(_on_intro_finished)

After the pan completes, IntroCam is freed and the player camera takes over. Clean handoff, no flash.

What’s next

Zone 00 exists. It has a background, camera limits, boundary walls, collision shapes (rough, needing tuning), and an intro cinematic.

Zone 01 — La Forêt des Passions — is partially done: the illustration is integrated, the script extends BaseZone, but no collision shapes yet. Twelve more zones after that.

The hardest part isn’t the code. It’s the image. Getting the right mood, the right composition, the right detail density for a world worth walking through.

I think we’re getting there.

— Thuan