Repository navigation
feat(cars): the M2O export streams each car with its own material library - #12
Merged
Merged
Conversation
…ials inside Mafia II Online now registers every archive a resource ships under stream/sds/cars/ by its file name and checks it before any player downloads it, so the export writes just package.json and the archives there: no vehicles.json, no file list, no table rows. A material the car uses that the game did not ship with travels inside its archive: the export writes those materials as an MTL library and embeds it as a MemFile named <name>.mtl, which the multiplayer adds through the game's LoadMTL. "Shipped with" is each library in edit\materials as it was before the toolkit first wrote it (its oldest backup). A car using a material no library has is refused, an export folder in the old layout is refused instead of mixed in, and empty material slots (hash 0) are ignored. --probe-car-m2o covers the layout, a car with only stock materials shipped byte for byte, an added material embedded in the archive that uses it and in no other, and the refusals.
The M2O export no longer embeds the materials a car adds as a MemFile inside its archive. They go into a library of their own, stream/materials/<name>.mtl, which Mafia II Online loads in addition to the game's libraries the way the game loads a mission pack's (LoadMTL), and releases when the player leaves the server. The same path serves any streamed content, not only cars, and the archives now always ship byte for byte as they were built. - The library is written through AtomicFile; MaterialLibrary gains ToBytes() for it. A re-export that adds nothing removes a stale one. - A car named with anything but a-z, 0-9 and _ is refused, as a server would; so is one that adds materials under a default* name, which would collide with the game's own libraries. - The result's EmbeddedMaterials becomes Materials (MCP model too). - --probe-car-m2o covers the library and the name refusal: 28/28.
A car exported under a new name had no row in the multiplayer and took vehicles.tbl's empty first row. Its archives now carry the row as a native table patch, /tables/patch_m2o<name>_vehicles.tbl, which the game appends while the car is loaded (how Joe's Adventures adds its cars). The row keeps the id and title text of the car it was made from: the game indexes per-car data by id, and the clone's text is local to its maker. A car under a stock name keeps the stock row. - GameTable.PatchRow builds a one-row patch of a table; GameTable.Name. - SdsManifest.AddTableEntry writes a Table entry (Type, NumTables, Table..., Version). - --probe-car-m2o checks each archive is the built one plus that row: 28/28.
raighen
added a commit
to raighen/illusion-toolkit
that referenced
this pull request
Oct 9, 2026
…ts own material library (mafia2online#12) car_export_m2o now writes the layout Mafia II Online streams: package.json, stream/sds/cars/<name>.sds with its winter twin, stream/materials/<name>.mtl for the materials the car adds, and the car's vehicles.tbl row inside its archives.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
car_export_m2onow writes exactly what Mafia II Online streams: the car's archive untouched, plus a material library when the car adds materials. Server owners drop the folder in and ship nothing else.Pairs with mafia2online/Mod#16, which adds streamed cars to M2O (that PR depends on MafiaHub/Framework#314).
What the export writes
vehicles.json, thesds/**file list, the table rows and the hashes. M2O registers each archive by its file name (a stock car's name replaces that car), so none of it is read any more.sds/cars+vehicles.json) is refused with a clear message instead of being mixed into.Materials travel as a streamed library
The meshes name materials by hash, and the game resolves them against the libraries in
edit\materials, which no server can change on a player's machine.default.mtl: a mission pack's, throughC_MaterialManager::LoadMTL, released again when the mission closes. M2O streams libraries the same way, for any content (cars now, city parts and crash objects later).edit\materialsas it was before the toolkit first wrote it. That's its oldest backup inbackups\, or the file itself if the toolkit never wrote it.default*name, whose library would collide with the game's own.The M2O server refuses a car that adds textures no streamed material uses, so a car exported without its library won't ship.
A clone carries its own vehicles.tbl row
Without a row, a new car takes the game's empty first row in M2O. The export now writes a clone's row into both archives as a native table patch,
/tables/patch_m2o<name>_vehicles.tbl, which the game appends while the car is loaded (how Joe's Adventures adds its cars).GameTable.PatchRowandGameTable.Name, plusSdsManifest.AddTableEntry.Tableentry.Testing
--probe-car-m2oagainst a real install (Steam, Mafia II Classic): 28/28 pass. It covers:Shubert_38's id 14 and title);package.json;stream/materials/<car>.mtlholds exactly it, the archives stay byte for byte, and a re-export without it removes the library;package.json, misnamed archive, a car name a server does not stream, unknown material.shubert_38_custom.sds, whoseFBI_Empire_BayandFBI_beaconaren't in the stock libraries).ExportFromwrote the untouched archive plus a 251-byteshubert_38_custom.mtl. Used unchanged as an M2O server resource:Shubert_38_Custom's row (id 14, 14 paint combos) instead of the empty row 0;Not covered
--probe-car-writeswas already failing before this PR: it lists 14 files outside its allow-list.CarM2oExportwas one of them before this change, and nothing here adds to that list.