diff --git a/src/Dummy/DummyPackage.php b/src/Dummy/DummyPackage.php
index 35451ca..ff2b3ab 100644
--- a/src/Dummy/DummyPackage.php
+++ b/src/Dummy/DummyPackage.php
@@ -14,7 +14,7 @@ class DummyPackage implements IPackage {
     }
 
     public function getVersion(): Version {
-        return new Version;
+        return new Version('1.2.3-beta1');
     }
 
     public function getFiles(): array {
@@ -33,16 +33,13 @@ class DummyPackage implements IPackage {
     }
 
     public function fwifSerialize(): array {
-        $data = [
+        return [
             'id' => $this->getId(),
             'name' => $this->getName(),
-            'ver' => $this->getVersion(),
+            'version' => $this->getVersion(),
             'files' => $this->getFiles(),
-            'targ' => $this->getTargets(),
-            'deps' => [],
+            'targets' => $this->getTargets(),
+            'deps' => $this->getDependencies(),
         ];
-        foreach($this->getDependencies() as $dependency)
-            $data['deps'][] = $dependency->getName();
-        return $data;
     }
 }
diff --git a/src/Dummy/DummyPackageTarget.php b/src/Dummy/DummyPackageTarget.php
index 2a4f0a5..d2c2285 100644
--- a/src/Dummy/DummyPackageTarget.php
+++ b/src/Dummy/DummyPackageTarget.php
@@ -20,13 +20,10 @@ class DummyPackageTarget implements IPackageTarget {
     }
 
     public function fwifSerialize(): array {
-        $data = [
-            'plat'  => $this->getPlatform(),
+        return [
+            'platform'  => $this->getPlatform(),
             'files' => $this->getFiles(),
-            'deps'  => [],
+            'deps' => $this->getDependencies(),
         ];
-        foreach($this->getDependencies() as $pack)
-            $data['deps'][] = $pack->getName();
-        return $data;
     }
 }
diff --git a/src/IPackage.php b/src/IPackage.php
index 0168b30..17d2667 100644
--- a/src/IPackage.php
+++ b/src/IPackage.php
@@ -4,6 +4,7 @@ namespace Patchouli;
 use FWIF\FWIFSerializable;
 
 interface IPackage extends FWIFSerializable {
+    function getId(): string;
     function getName(): string;
     function getVersion(): Version;
     function getFiles(): array;
diff --git a/src/Platform.php b/src/Platform.php
index 315ce47..a82d71f 100644
--- a/src/Platform.php
+++ b/src/Platform.php
@@ -105,15 +105,13 @@ class Platform implements FWIFSerializable {
     }
 
     public function matchOperatingSystem(Platform $other): bool {
-        if($this->getOperatingSystem() === '*'
-            || $other->getOperatingSystem() === '*')
+        if($this->getOperatingSystem() === '*' || $other->getOperatingSystem() === '*')
             return true;
         return $this->getOperatingSystem() === $other->getOperatingSystem();
     }
 
     public function matchArchitecture(Platform $other): bool {
-        if($this->getArchitecture() === '*'
-            || $other->getArchitecture() === '*')
+        if($this->getArchitecture() === '*' || $other->getArchitecture() === '*')
             return true;
         return $this->getArchitecture() === $other->getArchitecture();
     }
diff --git a/src/Version.php b/src/Version.php
index c8030ec..45b87fd 100644
--- a/src/Version.php
+++ b/src/Version.php
@@ -2,14 +2,70 @@
 namespace Patchouli;
 
 use FWIF\FWIFSerializable;
+use InvalidArgumentException;
 
 class Version implements FWIFSerializable {
+    private int $major;
+    private int $minor;
+    private int $patch;
+    private string $suffix;
+
+    public function __construct(string $version) {
+        $parts = explode('.', $version, 3);
+        if(count($parts) < 3)
+            throw new InvalidArgumentException('Invalid version string.');
+
+        $lastParts = explode('-', $parts[2], 2);
+        $this->major = (int)$parts[0];
+        $this->minor = (int)$parts[1];
+        $this->patch = (int)$lastParts[0];
+        $this->suffix = $lastParts[1] ?? '';
+    }
+
+    public function getMajor(): int {
+        return $this->major;
+    }
+
+    public function getMinor(): int {
+        return $this->minor;
+    }
+
+    public function getPatch(): int {
+        return $this->patch;
+    }
+
+    public function getSuffix(): string {
+        return $this->suffix;
+    }
+
     public function match(Version $other): bool {
-        return true;
+        return $this->getMajor() === $other->getMajor()
+            && $this->getMinor() === $other->getMinor()
+            && $this->getPatch() === $other->getPatch()
+            && $this->getSuffix() === $other->getSuffix();
+    }
+
+    public function compareTo(Version $other): int {
+        if($this->getMajor() !== $other->getMajor())
+            return $this->getMajor() - $other->getMajor();
+        if($this->getMinor() !== $other->getMinor())
+            return $this->getMinor() - $other->getMinor();
+        if($this->getPatch() !== $other->getPatch())
+            return $this->getPatch() - $other->getPatch();
+        if($this->getSuffix() === $this->getSuffix())
+            return 0;
+        if($this->getSuffix() === '')
+            return 1;
+        if($other->getSuffix() === '')
+            return -1;
+        return strcmp($this->getSuffix(), $this->getSuffix());
     }
 
     public function __toString(): string {
-        return '1.0.0';
+        $version = "{$this->getMajor()}.{$this->getMinor()}.{$this->getPatch()}";
+        if(!empty($suffix = $this->getSuffix()))
+            $version .= "-{$suffix}";
+        return $version;
     }
 
     public function fwifSerialize(): string {