diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -13,7 +13,11 @@
 
 main :: IO ()
 main = do
-  let parseFile f = fromRight (error $ "Unable to parse " <> f) . P.parse tscnParser "" <$> T.readFile f
+  let parseFile f =
+        fromRight (error $ "Unable to parse " <> f) . P.parse godotParser ""
+        <$> T.readFile f
   defaultMain [ bench "EntityMap" $ whnfIO (parseFile "bench/EntityMap.tscn")
               , bench "Geography" $ whnfIO (parseFile "bench/Geography.tscn")
+              , bench "MarketActor" $ whnfIO (parseFile "bench/MarketActor.tscn")
+              , bench "Other" $ whnfIO (parseFile "bench/Other.other")
               , bench "BigFile" $ whnfIO (parseFile "bench/BigFile.tscn")]
diff --git a/godot-megaparsec.cabal b/godot-megaparsec.cabal
--- a/godot-megaparsec.cabal
+++ b/godot-megaparsec.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               godot-megaparsec
-version:            0.1.0.0
+version:            0.2.0.0
 
 -- A short (one-line) description of the package.
 synopsis:           Megaparsec parser for Godot `tscn` and `gdns` files.
@@ -29,7 +29,9 @@
   location: https://github.com/WinstonHartnett/godot-megaparsec.git
 
 library
-  exposed-modules:  Godot.Parser.Resource
+  exposed-modules:
+    Godot.Parser.Resource
+    Godot.Parser.Resource.Lens
 
   -- Modules included in this library but not exported.
   -- other-modules:
diff --git a/src/Godot/Parser/Resource.hs b/src/Godot/Parser/Resource.hs
--- a/src/Godot/Parser/Resource.hs
+++ b/src/Godot/Parser/Resource.hs
@@ -1,30 +1,39 @@
-{-# LANGUAGE DeriveGeneric #-}
+{-|
+Module      : Godot.Parser.Resource
+Description : Megaparsec parser for the Godot resource file format.
+Copyright   : (c) Winston Hartnett, 2021
+License     : GPL-3
+Maintainer  : whartnett@gmail.com
+Stability   : experimental
+Portability : POSIX
 
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
+A parser for Godot resource file formats. Currently only supports auto-generated
+`tscn` and `gdns` files.
+-}
+{-# LANGUAGE DeriveGeneric #-}
 
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
 
 module Godot.Parser.Resource
   (GodotValue(..)
   ,GodotSection(..)
   ,TscnDescriptor(..)
   ,TscnParsed(..)
+  ,OtherDescriptor(..)
+  ,OtherParsed(..)
   ,GdnsDescriptor(..)
   ,GdnsParsed(..)
   ,GodotParsed(..)
   ,tscnParser
-  ,gdnsParser) where
+  ,gdnsParser
+  ,otherParser
+  ,godotParser) where
 
 import           Control.Applicative        ((<|>),liftA2)
-import           Control.Lens
 import           Control.Monad              (unless)
 
 import           Data.Char                  (isAlphaNum,isDigit,isUpper)
 import           Data.Either                (fromRight)
-import           Data.Foldable              (foldl')
 import           Data.Functor               (($>))
 import qualified Data.HashMap.Lazy          as M
 import qualified Data.HashSet               as S
@@ -35,6 +44,8 @@
 
 import           GHC.Generics               (Generic)
 
+import           Prelude                    hiding (exponent)
+
 import qualified Text.Megaparsec            as P
 import qualified Text.Megaparsec.Char       as P
 import qualified Text.Megaparsec.Char.Lexer as P (decimal,signed)
@@ -103,17 +114,19 @@
 godotValueP = do
   nc <- T.head . P.stateInput <$> P.getParserState
   case nc of
-    '"'       -> GodotString <$> godotStringP
-    '['       -> GodotArr <$> godotArrP
-    '{'       -> GodotDict <$> godotDictP
-    't'       -> GodotBool <$> godotBoolP
-    'f'       -> GodotBool <$> godotBoolP
-    'n'       -> godotNullP
+    '"' -> GodotString <$> godotStringP
+    '[' -> GodotArr <$> godotArrP
+    '{' -> GodotDict <$> godotDictP
+    't' -> GodotBool <$> godotBoolP
+    'f' -> GodotBool <$> godotBoolP
+    'n' -> godotNullP
     l
       | isUpper l || l == '@' -> GodotConstructor <$> godotConstructorP
-    _ -> P.try (GodotFloat <$> godotFloatP) <|> P.try (GodotInt <$> godotIntP)
+    _   -> P.try (GodotFloat <$> godotFloatP) <|> P.try (GodotInt <$> godotIntP)
 
 -- | Values parsed from a Tscn file.
+--
+-- Constructors are `(constructor name, constructor args)`.
 data GodotValue
   = GodotConstructor (T.Text, [GodotValue])
   | GodotInt Int
@@ -125,8 +138,6 @@
   | GodotNull
   deriving (Show,Generic,Eq)
 
-makeLenses ''GodotValue
-
 -- There aren't any lenses to unwrap sum types AFAIK :/
 -- Surely there's a better way to do this.
 unGodotConstructor k = fmap (\(GodotConstructor (n, a)) -> (n, a)) . M.lookup k
@@ -159,39 +170,45 @@
 
 collectRest its = M.filterWithKey (\k _ -> k `S.member` S.fromList its)
 
--- | As of Godot 3.3
+-- | Godot resource section prefixed with a bracket-enclosed header, optionally
+-- with body entries.
+--
+-- Header entries not specified in a record are accessed with the relevant `headers` field.
+-- Likewise, body entries not specified are accessed with the `entries` field.
+-- Note that explicitly specified section fields are not duplicated in `headers` and
+-- `entries` fields.
 data GodotSection
   = ExtResourceSection
     { _extResourceSectionPath    :: T.Text
     , _extResourceSectionTy      :: T.Text
     , _extResourceSectionId      :: Int
-      -- | Other header information
+      -- | Other header information.
     , _extResourceSectionHeaders :: M.HashMap T.Text GodotValue
-      -- | Body of the configuration entry
+      -- | Body of the configuration entry.
     , _extResourceSectionEntries :: M.HashMap T.Text GodotValue
     }
   | SubResourceSection
     { _subResourceSectionTy      :: T.Text
     , _subResourceSectionId      :: Int
-      -- | Other header information
+      -- | Other header information.
     , _subResourceSectionHeaders :: M.HashMap T.Text GodotValue
-      -- | Body of the configuration entry
+      -- | Body of the configuration entry.
     , _subResourceSectionEntries :: M.HashMap T.Text GodotValue
     }
   | NodeSection
     { _nodeSectionTy :: Maybe T.Text
     , _nodeSectionName :: T.Text
-      -- | If Nothing, then this node is the root
+      -- | If `Nothing`, then this node is the root.
     , _nodeSectionParent :: Maybe T.Text
-      -- | Instance is GodotConstructor
+      -- | Instance refers to an `ExtResource` ID, usually listed at the top of a file.
     , _nodeSectionInst :: Maybe Int
     , _nodeSectionInstPlaceholder :: Maybe T.Text
     , _nodeSectionOwner :: Maybe T.Text
     , _nodeSectionIndex :: Maybe Int
     , _nodeSectionGroups :: Maybe [T.Text]
-      -- | Other header information
+      -- | Other header information.
     , _nodeSectionHeaders :: M.HashMap T.Text GodotValue
-      -- | Body of the configuration entry
+      -- | Body of the configuration entry.
     , _nodeSectionEntries :: M.HashMap T.Text GodotValue
     }
   | ConnectionSection
@@ -199,9 +216,9 @@
     , _connectionSectionFrom    :: T.Text
     , _connectionSectionTo      :: T.Text
     , _connectionSectionMethod  :: T.Text
-      -- | Other header information
+      -- | Other header information.
     , _connectionSectionHeaders :: M.HashMap T.Text GodotValue
-      -- | Body of the configuration entry
+      -- | Body of the configuration entry.
     , _connectionSectionEntries :: M.HashMap T.Text GodotValue
     }
   | ResourceSection
@@ -216,8 +233,7 @@
     }
   deriving (Show,Generic)
 
-makeFields ''GodotSection
-
+-- | `tscn` file descriptor.
 data TscnDescriptor =
   TscnDescriptor
   { _tscnDescriptorLoadSteps :: Int
@@ -225,8 +241,7 @@
   }
   deriving (Show,Generic)
 
-makeFields ''TscnDescriptor
-
+-- | Parsed `tscn` file.
 data TscnParsed =
   TscnParsed
   { _tscnParsedDescriptor :: TscnDescriptor
@@ -234,8 +249,7 @@
   }
   deriving (Show,Generic)
 
-makeFields ''TscnParsed
-
+-- | `gdns` file descriptor.
 data GdnsDescriptor =
   GdnsDescriptor
   { _gdnsDescriptorTy        :: T.Text
@@ -244,8 +258,7 @@
   }
   deriving (Show,Generic)
 
-makeFields ''GdnsDescriptor
-
+-- | Parsed `gdns` file.
 data GdnsParsed =
   GdnsParsed
   { _gdnsParsedDescriptor :: GdnsDescriptor
@@ -253,15 +266,29 @@
   }
   deriving (Show,Generic)
 
-makeFields ''GdnsParsed
+-- | An unknown file descriptor.
+data OtherDescriptor =
+  OtherDescriptor
+  { _otherDescriptorHeaderName :: T.Text
+  , _otherDescriptorHeaders    :: M.HashMap T.Text GodotValue
+  }
+  deriving (Show,Generic)
 
+-- | An unknown file parsing result.
+data OtherParsed =
+  OtherParsed
+  { _otherParsedDescriptor :: OtherDescriptor
+  , _otherParsedSections   :: [GodotSection]
+  }
+  deriving (Show,Generic)
+
+-- | Parsed godot resource file.
 data GodotParsed
   = Tscn TscnParsed
   | Gdns GdnsParsed
+  | Other OtherParsed
   deriving (Show,Generic)
 
-makeFields ''GodotParsed
-
 tscnHeaderKVP :: Parser (T.Text, GodotValue)
 tscnHeaderKVP = liftA2 (,) (P.takeWhileP Nothing (/= '=')) (P.char '=' *> godotValueP)
 
@@ -337,6 +364,12 @@
    (unGodotString' "from" kvs) (unGodotString' "to" kvs) (unGodotString' "method" kvs)
    (collectRest ["signal", "from", "to", "method"] kvs) bodyKvs)
 
+-- | Parse an unspecified section.
+otherP :: Parser GodotSection
+otherP = do
+  (headerName, headerKvs', bodyKvs) <- bodyAndKvs
+  pure $ OtherSection headerName headerKvs' bodyKvs
+
 -- | Parse a `tscn` file.
 tscnParser :: Parser TscnParsed
 tscnParser = do
@@ -345,17 +378,17 @@
       format    = unGodotInt' "format" kvs
       sectionP  =
         P.choice
-        (map P.try [tscnConnectionP, tscnExtResourceP, tscnSubResourceP, tscnNodeP])
+        (map P.try
+         [tscnConnectionP, tscnExtResourceP, tscnSubResourceP, tscnNodeP, otherP])
   sections <- P.manyTill sectionP P.eof
   pure $ TscnParsed (TscnDescriptor loadSteps format) sections
 
 -- | Parse a `[resource]` section.
-resourceParser :: Parser GodotSection
-resourceParser = do
-  (headerName, headerKvs, bodyKvs) <- bodyAndKvs
-  pure
-    $ ResourceSection (unGodotString "resource_name" bodyKvs)
-    (unGodotString "class_name" bodyKvs) (unGodotConstructor "library" bodyKvs)
+resourceP :: Parser GodotSection
+resourceP =
+  headerWrapper "resource"
+  (\_ bodyKvs -> ResourceSection (unGodotString "resource_name" bodyKvs)
+   (unGodotString "class_name" bodyKvs) (unGodotConstructor "library" bodyKvs))
 
 -- | Parse a `gdns` file.
 gdnsParser :: Parser GdnsParsed
@@ -364,15 +397,19 @@
   let ty        = unGodotString' "type" kvs
       loadSteps = unGodotInt' "load_steps" kvs
       format    = unGodotInt' "format" kvs
-      sectionP  = P.choice (map P.try [tscnExtResourceP, resourceParser])
+      sectionP  = P.choice (map P.try [tscnExtResourceP, resourceP, otherP])
   sections <- P.manyTill sectionP P.eof
   pure $ GdnsParsed (GdnsDescriptor ty loadSteps format) sections
 
-otherParser :: Parser GodotSection
+-- | Parse an unknown resource file.
+otherParser :: Parser OtherParsed
 otherParser = do
-  (headerName, headerKvs, bodyKvs) <- bodyAndKvs
-  pure $ OtherSection headerName headerKvs bodyKvs
+  hName <- P.char '[' *> P.takeWhile1P Nothing (/= ' ') <* P.char ' '
+  hKvs <- headerKvs <* P.char ']' <* P.space
+  sections <- P.manyTill otherP P.eof
+  pure $ OtherParsed (OtherDescriptor hName hKvs) sections
 
--- | Parse a resource file (currently only `tscn` and `gdns`).
+-- | Parse some Godot resource file.
 godotParser :: Parser GodotParsed
-godotParser = P.try (Tscn <$> tscnParser) <|> P.try (Gdns <$> gdnsParser)
+godotParser =
+  P.choice (map P.try [Tscn <$> tscnParser, Gdns <$> gdnsParser, Other <$> otherParser])
diff --git a/src/Godot/Parser/Resource/Lens.hs b/src/Godot/Parser/Resource/Lens.hs
new file mode 100644
--- /dev/null
+++ b/src/Godot/Parser/Resource/Lens.hs
@@ -0,0 +1,28 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Godot.Parser.Resource.Lens where
+
+import           Control.Lens
+
+import           Godot.Parser.Resource
+
+makeLenses ''GodotValue
+
+makeFields ''GodotSection
+
+makeFields ''TscnDescriptor
+
+makeFields ''TscnParsed
+
+makeFields ''GdnsDescriptor
+
+makeFields ''GdnsParsed
+
+makeFields ''OtherDescriptor
+
+makeFields ''OtherParsed
+
+makeFields ''GodotParsed
