Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]
## Unreleased

### Added

### Changed

### Removed

## [0.2.0] - 2026-05-28

### Added
- `Toolkit` singleton class that acts as an entry point to the library.
- Global registry for game profiles, metaclasses, and symbol resolution.
- Centralized archive loading with automatic format detection.
- Object serialization/deserialization for MetaStream files.
- Must be initialized with `Toolkit.Initialize()` before use.
- Logging support.
- `HashDatabase` class - Thread-safe, in-memory symbol resolution database.
- Stores CRC64 -> Symbol name mappings with concurrent dictionary.
- Supports batch imports from text files and directories.
Expand All @@ -23,7 +32,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- Manages prioritized resource contexts, similar to Telltale Tool.
- Handles file extraction with proper override order (higher priority wins).
- Provides game-specific metaclass lookup and symbol resolution.
- Default MetaStream configuration derived from the game profile.
- Default `MetaStream` configuration derived from the game profile.
- Can create resource contexts from Lua resdesc files.
- `IFileProvider` interface - Common abstraction for file sources.
- Implemented by `ArchiveProvider`, `FolderProvider`, and `LooseFileProvider`.
- Supports lookup by both CRC64 and filename.
Expand All @@ -36,19 +46,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- Workspace-level `LocalHashDatabase` for game-specific symbols.
- Automatic fallback: global DB -> workspace DB -> mounted file names.
- Batch resolution with `ResolveSymbols()`.
- Various new T3Types for compatibility with MSV5 and MSV6 games.
- Various new T3Types for compatibility with MTRE, MSV5 and MSV6 games.
- Support for `resdesc` (#1).
- Support for container streams (#18).
- Experimental support creating archives. (#18)
- Experimental `PropertySet` serializer.
- Helper methods for `T3Texture` and `PropertySet`.
- Serializers for `D3DMesh` related classes.
- Some animation/skeleton related types in the type registry.
- New contributor in README.md.
- New contributors in README.md.

### Changed
- `GameDescriptor` renamed to `GameProfile` to better reflect its purpose.
- `GameContext` renamed to `Workspace` for clarity.

- Moved `Lua` relate
- Some `T3Texture` members now have default values.
- Some class members now have default values.
- Renamed `TelltaleFileEntry` to `ResourceEntry` to match Telltale's naming.
- Renamed, reorganized and refactored various classes in `TelltaleArchives`. (#18)
- Refactored `Symbol`. (#14)
- NuGet related metadata in `TelltaleToolKit.csproj`.
- Package the data folder as `ttk-data`.

### Removed
- `TTKContext` singleton class. It has been replaced by `Toolkit`.
Expand All @@ -58,7 +74,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Fixed
- Due to the heavy refactoring, most old bugs do not apply to this version.
- Various bugs regarding loading and saving have been fixed.
- `Save<T>` without a configuration now works properly.

## [0.1.0] - 2025-09-30

Expand All @@ -67,6 +82,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- Initial support for the following file formats: `.aam`, `.amap`, `.anm`, `.aud`, `.chore`, `.d3dmesh`, `.d3dtx`, `.dlg`, `.dlog`, `.dss`, `.font`, `.imap`, `.landb`, `.lanreg`, `.lang`, `.langdb`, `.langres`, `.ldb`, `.locreg`, `.look`, `.note`, `.overlay`, `.ptable`, `.prop`, `.rules`, `.save`, `.scene`, `.skl`, `.style`, `.tmap`, `.vox`, `.wbox`. Currently most serializers are **unfinished and unreliable, especially in writing mode**. Over time, they will get polished and refined.
- Registration system for types, metaclasses, type serializers and game descriptors (game configurations).

[unreleased]: https://github.com/iMrShadow/TelltaleToolKit/compare/0.1.0...HEAD
[unreleased]: https://github.com/iMrShadow/TelltaleToolKit/compare/0.2.0...HEAD
[0.2.0]: https://github.com/iMrShadow/TelltaleToolKit/releases/tag/0.2.0
[0.1.0]: https://github.com/iMrShadow/TelltaleToolKit/releases/tag/0.1.0

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2025 Ivan Panayotov
Copyright (c) 2025-2026 Ivan Panayotov

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
68 changes: 35 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@

## Features

- Open and extract files from `.ttarch` and `.ttarch2` archives.
- Open, edit, and save file formats (textures, meshes, sounds, and more).
- Extract and create archive files (`.ttarch` and `.ttarch2`).
- Open, edit, and save assets (textures, meshes, sounds, and more).
- Create environments for working with assets of a specific Telltale game with resource contexts.
- Modular and flexible registration system (types, metaclasses, serializers, per-game configs).
- Create and manage a simple SQLite hash database.
- Cross-platform: Windows, Linux, Mac (requires .NET 8.0 or later).
- Create and manage simple hash databases.
- Cross-platform: Windows, Linux, Mac (requires .NET 8.0 or later, or .NET Standard 2.1).
- For more details, check the [documentation folder](docs/README.md).

## Installation
Expand All @@ -39,48 +40,43 @@ Install-Package TelltaleToolKit
```
Or add it to your .csproj file:
```xml
<PackageReference Include="TelltaleToolKit" Version="0.1.0" />
<PackageReference Include="TelltaleToolKit" Version="0.2.0" />
```

You must also download the latest database from the data folder. You can use [this link](https://downgit.github.io/#/home?url=https://github.com/iMrShadow/TelltaleToolKit/tree/main/data).
The Nuget package ships a default database, but if you want the latest one - you can download it from [this link](https://downgit.github.io/#/home?url=https://github.com/iMrShadow/TelltaleToolKit/tree/main/data).

## Usage

```csharp
using TelltaleToolKit;
using TelltaleToolKit.Serialization.Binary;
using TelltaleToolKit.T3Types.Textures;
using TelltaleToolKit.T3Types.Textures.T3Types;
using TelltaleToolKit.Utility;

// Set up the context from a folder.
TTKContext.Instance().Load("../../../../../data");
// 1. Initialize the library.
Toolkit.Initialize();

// (Recommended) Set the active game for default configuration.
// This is not required, if you only read files.
TTKContext.Instance().SetActiveGame("the-walking-dead-definitive-series-2019");
// 2. Create a workspace for the target game.
Workspace workspace = Toolkit.Instance.CreateWorkspace(
"The Walking Dead Workspace",
gameProfile: "The Walking Dead: Definitive Series");

// Load a Telltale archive.
using var archive = TTK.Load("WDC_pc_WalkingDead404_txmesh.ttarch2", T3BlowfishKey.Twdc);
// 3. Mount the game data.
workspace.LoadArchive("WDC_pc_WalkingDead404_txmesh.ttarch2", contextName: "WalkingDead404 Textures");

// Extract a file from the archive in a stream.
var blob = archive.ExtractFile("obj_backpackClementine400.d3dtx");
// 4. Load an asset.
T3Texture? texture = workspace.LoadAsset<T3Texture>("obj_backpackClementine400.d3dtx");

// Load the d3dtx from a stream.
var d3dtxObj = TTK.Load<T3Texture>(blob, out MetaStreamConfiguration config);
if (texture != null)
{
// 5. Modify it.
texture.Name = "obj_backpackClementine400_modified";
texture.SurfaceFormat = T3SurfaceFormat.ARGB8;
texture.Width = 1024;
texture.Height = 1024;

// Alternatively, load the texture directly from the filesystem.
// Replace the path with a valid one.
// TTK.Load<T3Texture>("obj_backpackClementine400.d3dtx", out config);

// Modify the texture.
d3dtxObj.Name = "My new modified texture!";
d3dtxObj.SurfaceFormat = T3SurfaceFormat.ARGB8;
d3dtxObj.Width = 1024;
d3dtxObj.Height = 1024;

// Save the modified texture on the filesystem.
TTK.Save(d3dtxObj, "new_modified.d3dtx", config);
// 6. Export it back to disk.
workspace.ExportAsset(texture, "obj_backpackClementine400_modified.d3dtx");
}
```

## API Documentation
Expand All @@ -97,6 +93,14 @@ This project is licensed under the MIT License. See the [LICENSE](https://github

## Credits

Thanks to [Gamma_02](https://github.com/gamma-02) for contributing a lot to this project such as adding resdesc parser and many improvements to the API. The Lua decompiler is based on their [UnLuaCSharp](https://github.com/gamma-02/UnLuaCSharp) library.

Thanks to [Knollad Knolladious](https://github.com/LBPHaxMods) for adding `D3DMesh` serialization support.

Thanks to [Plague](https://x.com/QueenPlagueCure) for providing version databases for "Borderlands" (2021, PC and Nintendo Switch).

Thanks to Pumba for providing version databases for "The Wolf Among Us".

Thanks to [Lucas Saragosa](https://github.com/LucasSaragosa) for his outstanding work on [`TelltaleToolLib`](https://github.com/LucasSaragosa/TelltaleToolLib/tree/main), [`Telltale Inspector`](https://github.com/LucasSaragosa/TelltaleInspector) and [`Telltale Editor`](https://github.com/Telltale-Modding-Group/Telltale-Editor), which made me understand Telltale's meta system.

Thanks to [Luigi Auriemma](https://aluigi.altervista.org/index.htm) for their [`ttarchext`](https://aluigi.altervista.org/papers.htm#others-file), which laid much of the groundwork for `.ttarch` and `.ttarch2` extraction.
Expand All @@ -109,6 +113,4 @@ Thanks to [Azil Zogby](https://github.com/asilz) for his work on [`TelltaleHydra

Thanks to all [contributors](https://github.com/stride3d/stride/graphs/contributors) which worked on the popular C# game engine [`Stride`](https://github.com/stride3d/stride). The serialization system is inspired from there.

Thanks to [Plague](https://x.com/QueenPlagueCure) for providing version databases for Borderlands 2021 PC and Nintendo Switch.

Thanks to [David Matos](https://github.com/frostbone25) for introducing me to the `Telltale Modding Community`.
16 changes: 14 additions & 2 deletions data/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,27 @@
#### Version Database
- Added initial version database for The Wolf Among Us (2013)

### 28th of April, 2026

#### Game Profiles
- Added a game profile and its corresponding version database for "The Walking Dead (2012)".

#### Version Database
- Added new metaclass descriptions to the global database.
- Added initial MTRE types which mainly support "The Walking Dead (2012)". This indirectly adds support for other MTRE games which were released relatively early to the game such as "Jurassic Park: The Game (2011)" and "Back to the Future: The Game (2010)", but this requires further testing.
- Added more MSV5 types which affect "The Walking Dead: Season 2 (2013)" and "The Wolf Among Us (2013)". These types used non-fixed-width primitive types (like ```int``` or ```unsigned long```) which affected almost all CRC32 checksums.
- Added more class description mappings for "The Walking Dead: Season 2 (2012)"
- Registered new types.

### 24th of April, 2026

#### Game Profiles
- Added the year to TWDS2 game profile json file name to match other entries
- Added the year to TWDS2 game profile json file name to match other entries (Thank you @gamma-02)

### 17th of March, 2026

#### Game Profiles
- Added initial game profile for Poker Night at the Inventory Remastered (2026)
- Added initial game profile for Poker Night at the Inventory Remastered (2026) (Thank you @gamma-02)

#### Version Database
- Added initial version database for aforementoned Poker Night at the Inventory Remastered (2026)
Expand Down
23 changes: 11 additions & 12 deletions data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ You can find the [changelog here](./CHANGELOG.md).
- [Overview](#overview)
- [Database Categories](#database-categories)
- [File Naming \& Standards](#file-naming--standards)
- [Game Descriptor Fields](#game-descriptor-fields)
- [Game Descriptor Full Example](#game-descriptor-full-example)
- [Game Profile Fields](#game-profile-fields)
- [Game Profile Full Example](#game-profile-full-example)
- [Supported Games Matrix](#supported-games-matrix)
- [Contributing](#contributing)
- [FAQ](#faq)
Expand All @@ -24,22 +24,21 @@ The library relies on a set of structured databases to support a wide variety of

There are three main categories of databases:

1. **Game Descriptors**
1. **Game Profiles**
- **Purpose:** Defines general configuration for each supported game.
- **Format:** JSON file (extension: `.json`)
- **Aliases:** Game snapshots, game configurations.
- **Aliases:** Game snapshots, game configurations, game descriptors.

2. **Version Databases**
- **Purpose:** Describes metaclass descriptions for a given game.
- **Purpose:** Maps types to their corresponding CRC32 versions per game. `global.vdb.json` holds all metaclass descriptions.
- **Format:** JSON file (extension: `.vdb.json`)
- **Aliases:** Metaclass description databases.
- **Note:** Version databases **require a game descriptor to function with the same slug**.
- **Note:** Version databases **require a game profile to function with the same slug**.

3. **Hash Database(s)** (Planned/Experimental)
- **Purpose:** Contains SQLite databases with file hashes unique to each game.
- **Format:** SQLite database file (extension: `.db`)
3. **Hash Database(s)**
- **Purpose:** Used for reverse-engineering symbols. Hash databases store strings that are converted to symbols at run-time.
- **Format:** Text File `.txt`
- **Aliases:**
- **Note:** Do not try to implement any hash databases on your own as of now.

## File Naming & Standards

Expand All @@ -57,7 +56,7 @@ For consistency, all database file names are in slug form with the appropriate e
- `the-walking-dead-2012.json`
- `the-wolf-among-us-2013.vdb.json`

## Game Descriptor Fields
## Game Profile Fields

| Field | Type | Description | Example |
| ------------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
Expand All @@ -71,7 +70,7 @@ For consistency, all database file names are in slug form with the appropriate e
| `AreSymbolsHashed` | `bool` | Whether the game's symbols are hashed (`true` or `false`). This should almost always be `true`. Only `MBIN` are allowed to not be hashed. | `true` |
| `EnableOodleCompression` | `bool` | Whether Oodle compression is enabled for game archives. | `false` |

### Game Descriptor Full Example
### Game Profile Full Example

```json
{
Expand Down
6 changes: 3 additions & 3 deletions samples/VersionDatabaseCreator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ await Parallel.ForEachAsync(archivePaths, async (filePath, _) =>

if (archive.Entries.Values.Any())
{
Stream firstFile = archive.OpenResource(archive.Entries[0].Name);
Stream? firstFile = archive.OpenResource(archive.GetAllEntries().First().Name);

if (Toolkit.IsMetaFile(archive.Entries[0].Name))
if (Toolkit.IsMetaFile(archive.GetAllEntries().First().Name))
{
MetaStreamConfiguration config = new MetaStreamReader(firstFile).Configuration;

Expand All @@ -81,7 +81,7 @@ await Parallel.ForEachAsync(archivePaths, async (filePath, _) =>
{
// Console.WriteLine($"Reading {entry.Name}");

using Stream file = archive.OpenResource(entry.Name);
using Stream? file = archive.OpenResource(entry.Name);

if (!Toolkit.IsMetaFile(file))
continue;
Expand Down
4 changes: 2 additions & 2 deletions src/TelltaleToolKit/TelltaleToolKit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<AnalysisLevel>latest</AnalysisLevel>
<LangVersion>13</LangVersion>
<RootNamespace>TelltaleToolKit</RootNamespace>
<Version>0.1.0</Version>
<Version>0.2.0</Version>
<Title>TelltaleToolKit</Title>
<Authors>Ivan Panayotov</Authors>
<PackageProjectUrl>https://github.com/iMrShadow/TelltaleToolKit</PackageProjectUrl>
<RepositoryUrl>https://github.com/iMrShadow/TelltaleToolKit</RepositoryUrl>
<PackageTags>telltale; ttarch; ttarch2; modding;</PackageTags>
<PackageTags>telltale; ttarch; ttarch2; modding; d3dtx; d3dmesh; lenc; dlog; skunkape; langdb; prop; skl; chore</PackageTags>
<Description>A .NET library for modding games running on the Telltale Tool engine, providing an API to read and write assets and archives.</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReleaseNotes>https://github.com/iMrShadow/TelltaleToolKit/releases</PackageReleaseNotes>
Expand Down
4 changes: 2 additions & 2 deletions tools/TTKDatabaseGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ await Parallel.ForEachAsync(archivePaths, parallelOptions, async (filePath, _) =

if (archive.Entries.Count > 0)
{
await using Stream? firstFile = archive.OpenResource(archive.Entries[0].Name);
await using Stream? firstFile = archive.OpenResource(archive.GetAllEntries().First().Name);

if (Toolkit.IsMetaFile(archive.Entries[0].Name))
if (Toolkit.IsMetaFile(archive.GetAllEntries().First().Name))
{
MetaStreamConfiguration config = new MetaStreamReader(firstFile).Configuration;
areSymbolsHashed = config.AreSymbolsHashed;
Expand Down
Loading