Skip to main content

GD Parse

A Python library for parsing, modifying, and serializing Geometry Dash level data. It allows you to decrypt level strings obtained from the game or servers, interact with level components like headers, colors, and objects in a structured way, and then serialize and re-encrypt them.

Installation

pip install gdparse

Core Features

  • Decrypt Geometry Dash level strings.
  • Parse decrypted level data into structured Python objects (GDLevel, LevelObject).
  • Access and Modify level headers, color channels, and individual objects.
  • Add new objects or Remove existing ones programmatically.
  • Create new, empty levels with default settings.
  • Serialize GDLevel objects back into the GD string format.
  • Encrypt level data strings for use in Geometry Dash.
  • Automatically Detect level format versions (1.0, 1.9, 2.0+).
  • Optionally Filter out Triggers during parsing for simpler analysis or modification.

Usage Examples

1. Decrypting and Parsing a Level

from gdparse import GDLevelCrypto, GDLevel, LevelObject

# Example encrypted level string (replace with your actual level string)
encrypted_level_string = "1:114027874:2:Placeholder:3::4:H4sIAAAAAAAACq1TyQ3DMAxbyAVEHTmQV2foABogK3T4WmaeCdqifYSMQ4qSDGR_2NKQLqkJjbTUiARISuJHzxtySohIzolEFCwpuSSeyBEh-lkEfo9YTyPKw4KPQjSr_izoqyvp598z_PJOuA76ym_Wict1vryX6V9BZ0u1_Q5rUhSkieStI9_ngXroPGEpethKbSBzhnD3gVQhNNGltCkdOjeUXUgg6SBllDLFqBk142jOMGeYB8upmdHpJI5v7Fd_WtE6CMcWrNNjXHD4Tlu17n2jWQGiP9sLnB56Wa8DAAA=:5:2:6:237923769:8:0:9:0:10:21:12:0:13:22:14:-2:17::43:0:25::18:0:19:0:42:0:45:4:15:0:30:0:31:0:28:1 hour:29:1 minute:35:0:36::37:0:38:0:39:1:46:31:47:0:40:0:57:682:27:Aw==#018ee041b2ee5de52963da287055a4e3274d01b1#b31d3fe59b458bcddaac801f5106a4e4f2df9567"

try:
    # Decrypt the level string
    decrypted_data = GDLevelCrypto.decrypt(encrypted_level_string)
    print("--- Decrypted Level Data ---")
    # print(decrypted_data) # Usually very long, print sparingly

    # Parse the decrypted data into a GDLevel object
    # Set ignore_triggers=False if you want to include triggers
    gd_level = GDLevel(decrypted_data, ignore_triggers=True)

    print("\n--- Parsed GD Level Info ---")
    print(f"Level Version Detected: {gd_level.version}")
    print(f"Number of Objects (excluding triggers): {len(gd_level.objects)}")
    # print(gd_level) # Print full details if needed

except ValueError as e:
    print(f"Error processing level: {e}")

2. Accessing and Modifying Level Data

# Assuming 'gd_level' is the parsed GDLevel object from the previous example

if gd_level:
    # Access Headers
    print("\n--- Level Headers ---")
    # Print a few common headers if they exist
    print(f"Background ID: {gd_level.headers.get('k2')}")
    print(f"Ground ID: {gd_level.headers.get('k3')}")
    print(f"Music ID: {gd_level.headers.get('k4')}")
    # print("All Headers:", gd_level.headers)

    # Access Colors (structure depends on version)
    print("\n--- Level Colors ---")
    if gd_level.version == "2.0+":
        bg_color = gd_level.colors.get(1) # Channel 1 is usually BG
        if bg_color:
            print(f"Background Color (Ch 1): RGB({bg_color['r']}, {bg_color['g']}, {bg_color['b']}) Opacity: {bg_color['opacity']}")
    # print("All Colors:", gd_level.colors)

    # Access and Modify Objects
    if gd_level.objects:
        first_object = gd_level.objects[0]
        print("\n--- Modifying First Object ---")
        print(f"Original First Object Position: ({first_object.properties.get(2)}, {first_object.properties.get(3)})")

        # Change its position (key 2 is X, key 3 is Y)
        first_object.properties[2] = first_object.properties.get(2, 0) + 60 # Move 60 units right
        first_object.properties[3] = 105 # Set Y to 105

        print(f"Modified First Object Position: ({first_object.properties.get(2)}, {first_object.properties.get(3)})")

    # Add a new object
    print("\n--- Adding New Object ---")
    new_block = LevelObject.create_block(
        block_id=21,  # Spike block ID
        x=150,
        y=105
    )
    gd_level.add_object(new_block)
    print(f"Added new object: {new_block}")
    print(f"New total object count: {len(gd_level.objects)}")

3. Serializing and Encrypting a Level

# Assuming 'gd_level' is the potentially modified GDLevel object

if gd_level:
    try:
        # Serialize the GDLevel object back into a string
        serialized_level_data = gd_level.serialize()
        print("\n--- Serialized Level Data ---")
        # print(serialized_level_data) # Can be very long

        # Encrypt the serialized data
        # Set is_official_level_music appropriately if needed (rarely true for user levels)
        re_encrypted_string = GDLevelCrypto.encrypt(serialized_level_data, is_official_level_music=False)
        print("\n--- Re-encrypted Level String ---")
        print(re_encrypted_string)

    except Exception as e:
        print(f"Error serializing or encrypting: {e}")

4. Creating an Empty Level

from gdparse import GDLevel, LevelObject, GDLevelCrypto

# Create a new empty level (defaults to version 2.0+)
empty_level = GDLevel.create_empty(version="2.0+")

print("--- Created Empty Level ---")
print(f"Version: {empty_level.version}")
print(f"Initial Objects: {len(empty_level.objects)}")
print(f"Initial Colors: {empty_level.colors}")

# Add a starting block
start_block = LevelObject.create_block(block_id=1, x=0, y=75)
empty_level.add_object(start_block)
print(f"Objects after adding start block: {len(empty_level.objects)}")

# Serialize and encrypt the new level
serialized_empty = empty_level.serialize()
encrypted_empty = GDLevelCrypto.encrypt(serialized_empty)

print("\n--- Encrypted Empty Level String ---")
print(encrypted_empty)

Disclaimer: This library code and README were generated with the assistance of an AI because the author is lazy. Use at your own risk.

Metadata

Release files for gdparse 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gdparse 0.3.0
File Size Uploaded
gdparse-0.3.0.tar.gz 10.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gdparse 0.3.0
File Interpreter ABI Platform
gdparse-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 19.1 kB

Release files / gdparse-0.3.0.tar.gz

Download URL gdparse-0.3.0.tar.gz
Size 10.0 kB
Tags Source
SHA-256 checksum
How to use checksums
7c5fc65c7793b47fad5923d5528b282de9ef2616336f71b49659772b4eb1851f
BLAKE2b-256 checksum
How to use checksums
3fa61a8c386bd06cedc1de951477b9c35d6032356fa2326d7b7dacbc38cc1533
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.10.6

Release files / gdparse-0.3.0-py3-none-any.whl

Download URL gdparse-0.3.0-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
91feec1d87353fdeefebf804ee7ce325daf11cb59d27432e8318645436a70020
BLAKE2b-256 checksum
How to use checksums
d0ee5634031dd6585cb6d4e5c1f12beaaacb80d6869722dc58d4ff9169fe0ffb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.10.6

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page