Above the packet list: each property the capture was on, its owner, and every
model placed, moved or removed, each jumping to its packet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In a capture replay, each model stands where the capture saw it at the
playhead (the UGC server's mesh for a brick built model when it has one, a box
otherwise), appearing, moving and vanishing with the timeline both ways; the
Property tab shows the property data of that moment and the models standing,
and behavior messages are ticks on the timeline. In a replay of recorded
positions on one property instance, the models placed now are drawn and
labelled as now.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/api/world3d/property_models?zone=&clone= lists the saved property's models
(LOT, name, UGC ID, position, rotation), for replays of recorded positions,
which don't record models.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/api/inspector/sessions/:id/property serves CaptureProperty's worlds, built
once per loaded capture on a worker after the replica pass, with the zone's
and the models' names from the locale and the property saved now for each
zone and clone (read on the main thread) for links and UGC meshes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CaptureProperty::Build reads, per world of a capture, the property it was:
each model (constructed with a model component, or a brick built model) with
its LOT, object, spawner, blueprint and behavior count and where it stood per
time span, from its constructions, serializations and destruction; the
DownloadPropertyData of that map and the GetModelsOnProperty counts; and the
events: placed (a PlaceModelResponse with the model made at that position,
before or after it), moved, removed (with the DeleteModelFromClient reason),
editing, and behavior messages.
CaptureTool property <bundle> --cdserver prints it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A compressed construction config is a u32 uncompressed size, a u32 compressed
size and the zlib bytes: the reader took the first size for the second and lost
its place, so live model constructions never read. It now inflates and reads
the entries.
A model's item component isn't made (Entity::Initialize): its model component
writes the item info. The layout left the registry's item component in, so a
premade model's components read one block twice and didn't match. Live writes
the same bits from its item component, so both now read exactly.
Tested with a live placed model's construction and the server's own model.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The account page lists the account's reports as a table and the Client System Info page lists every report (or each account's newest), sortable and searchable by account name or video card; a row opens every field. Values that say little about the real system are marked, and every caveat is a tooltip on the value and column.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
How to build blocklist.dcf from blocklist.txt and where it goes, the
version 3 layout and hash, what happens to old files, and blocked
phrases; README "This branch" line. issue 215
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocked entries marked Phrase, no Allow for a phrase, phrase matches named
in the message test, and the Word files section says when blocklist.dcf
is in the old format and how to rebuild it from blocklist.txt. issue 215
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shipped list's hashes are 64-bit FNV-1a (checked against a sample of
its words), so it is written again as version 3: same hashes, duplicates
dropped, sorted. Nothing else changes; it can be replaced by building
from blocklist.txt. issue 215
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The filter stored and compared words by std::hash<std::string> in size_t,
which differs between standard libraries and platforms, so a .dcf made on
one system never matched on another and the block list never worked
there (issue 215).
- ChatFilterCore.h: 64-bit FNV-1a over the entry's bytes, ASCII lower
case, fixed-width uint64_t everywhere stored or compared.
- .dcf version 3: little-endian magic, version, longest entry in words,
uint64 count and sorted uint64 hashes. Version 2 files are refused:
the allowed words cache is rebuilt from its .txt, an old
blocklist.dcf is logged as unreadable.
- The servers build blocklist.dcf from a plain blocklist.txt next to
them (one word or phrase per line) when it is newer.
- Blocked entries can be phrases: runs of consecutive words up to the
longest entry, the whole run marked. Whitelist chat still checks one
word at a time, as the client does.
- Dashboard: the chat filter API reads blocklist.dcf the same way
(status, phrase length), accepts blocked phrases, refuses allowed
ones, and explains phrase matches in its message test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pet chasing across a "PR - Pet Blocker" stops in front of it; a
carver_only navmesh carver added without an object stops an enemy and goes
away with the physics world; carver_only alone blocks nothing; a Robot City
hedge's blocker has the size and offset of its collision shape.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The client never loads a level object whose config has carver_only set (its
resource manager skips the load; LWOBasePhysComponent::LoadConfigData
0x00c495c9 reads the flag next to navmesh_carver), and live never sent one:
none of the 331 carver_only placements (mostly Crux Prime's trigger boxes)
shows up among the live constructions, where their zones' other objects do.
DLU spawned them as objects.
They are skipped now. The ones that carve the navmesh (53, in six zones,
among them the Avant Gardens Sentinel camp walls) still stop the server's movers: their shape
goes into the world's movement blockers without an object, owned by the
physics world (dpWorld::AddOwnedMovementBlocker) and freed when it shuts
down. None of them has a script, trigger or group.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Walls whose asset shape the server doesn't know are left out of the movement
blockers (a stand in cube would be a guess), which left out every navmesh
carver in Robot City (hedges, hedge corners, potted bushes, greebles, robot
statues) and the Ninjago Monastery benches. Their sizes now come from the
client's own collision shapes (res/physics): the bounds of all of a shape's
parts, with the offset of the box from the object's position. The hedge
corner is an L, so its box also covers the inside of the corner.
The same bounds match two shapes the server already had (misc_phys_10x1x5:
10 x 5 x 1; Trigger_Rectangle_Box: 8 x 8 x 4).
CreatePhysicsEntity's shape lookup becomes CreateAssetShape, which needs no
component, for walls without an object.
Still unknown: the Ninjago Monastery cave's primitive model carver (a 77.6
cube whose origin, centre or base, isn't known).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pets are walked by the server's MovementAI like enemies, but only enemies'
paths were cut at movement blockers, so pets walked through the Nimbus Station
pet ranch's "PR - Pet Blocker" walls. Their collision group (3) is the one
the pet blocker's group (18) touches in the client's collision filter, so a
pet's path now stops at them (and at navmesh carvers), whether wandering or
following its owner; a pet left behind still warps to its owner.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers the key names and name value types, a pickup from an object, from the
player and from an object that is gone, metrics after an item's config (and
not kept on the item), a removal's loot source, and a quickbuild taking its
item cost with itself as the source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live's RemoveItemFromInventory for a quickbuild's item cost (the FV Stone
Warrior pedestal's 5 Maelstrom Infected Bricks, taken when the build starts)
had the loot source Quickbuild and the quickbuild's object ID as the loot
source object. DLU sent loot source None with no source.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The other item sources live marked in AddItemToInventoryClientSync's extra
info, with the keys and values live sent:
- mission and achievement rewards: _Metric_Mission_ID_Int and source LOT 1,
the player (225 of 225 live rewards)
- activity rewards: _Metric_Activity_ID_Int and the activity object's LOT
- vendor purchases: the vendor's LOT and _Metric_Currency_Delta_Int, the coins
paid as a negative number (left out when the item costs no coins)
- mail attachments: _Metric_Mail_ID_Int64
- traded items: _Metric_Transaction_ID_Int64, the trade's ID
Loot::GiveLoot gains overloads that pass them on.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live's AddItemToInventoryClientSync for a picked up drop had
_Metric_Souce_LOT_Int in its extra info on all 2,344 live pickups: the LOT
of the DropClientLoot's source object, 1 when a player was the source
(activity rewards and chests, which drop from the player). DLU sent none.
The drop remembers its source object's LOT when it is registered for the
player, and the pickup sends it. A source object already gone when it drops sends
no key. Package contents keep sending none, as live's did.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live servers put _Metric_ keys in AddItemToInventoryClientSync's extra info,
after the item's own config, saying where the items came from: the source
object's LOT (_Metric_Souce_LOT_Int, misspelt as live had it), the mission,
activity, coins paid, mail or trade. LootMetrics holds them and writes them
with the key names and name value types live used (the mail ID as type 8,
the trade ID as type 9). AddItem, ReceiveItem (its options), the new item
constructor and Item::SetCount pass them through to the message; the item
does not keep them.
RemoveItem and Item::SetCount can also say what took items away
(ItemRemovalSource), filling RemoveItemFromInventory's loot source and
source object instead of none.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The replay speed saved for recorded positions (60x by default) is for scrubbing through hours of movement. A capture is minutes long and played too fast at that speed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every LU MessageType has a struct or is listed as never used by this server; every game message struct reads;
samples of each family and of sent game messages read back; replica constructions, updates and destructions written
by the server's own serializers read back. Generator finds constructors defined in the .cpp.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Links the game for its message structs, reads the components of every LOT at startup, and decodes a capture's
replica packets once, in timeline order, on a worker thread.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReplicaDecoder mirrors Entity::WriteBaseReplicaData and each component's Serialize, keeps what each network ID is
per world instance, and shows the rest as bits when no layout fits. CaptureTool links the game: game messages are
decoded (and compared in replays), and decode --cdserver reads replica packets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GameMessageDecoder reads every NetGameMsg struct (generated member lists in GameMessageFields.inc) instead of 10
hand-written ones; DisplayTooltip gets the Deserialize it lacked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The capture viewer's LU packet fields come from each struct's Deserialize and a member list generated from the
struct definitions (tools/gen_game_message_fields.py -> dNet/PacketFields.inc), replacing the hand-written list of
25. Secret members are never listed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A list cut short inside the flags was read as if complete; an older master's list, which has none, still
reads. The test checks every cut.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MATCH_TRANSFER is appended after GUILD_DISBAND (71); the chat ids from
CREATE_TEAM on are pinned.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Busy property instances on changed files are kept (KEEP_UNTIL_EMPTY) instead
of saved, frozen and moved. Every instance acted on is marked outdated; the
files status carries the flag (bit 4).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Property instances are left out of the replace plan. Once the database is
up to date every instance running at the start is marked outdated, and a
zone that already got a new instance is not started again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Instances on an old binary or old zone files are marked outdated: routing,
private passwords and merges skip them. Outdated properties remind their
players every 10 minutes that an update is waiting (ANNOUNCE) and stop once
empty. A new instance of the same property waits for the old one to be gone
before its world server starts, so two worlds never save one property.
The server list carries the flag after the endpoints (read when present).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Metal was drawn with metalness 1 in the room environment at half strength with one
sun, so metal groups came out nearly black. The game's metal keeps the vertex
color (lit, plus a reflection tinted by it), so metal is now part metal with a
stronger reflection, the environment is brighter and a sky over ground fill
lights the sides away from the sun.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LU Toolbox's metallic table also has colors the client's Materials.xml types
shinyPlastic, such as 131, the grey of many baseplates, so whole baseplates went
into S88_Metal_Model. Metal now comes from the Materials.xml types (shinySteel)
and the settings' colors only; the table still gives colors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live: when the position feed reports the followed player only in another world,
load its scene, keep following and toast where they went. Capture playback: load
every zone's movement, switch the scene at the followed character's world change
(forward and when seeking back), follow a lone captured character from the start,
and mark world changes on the replay slider.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
followedMove (live feed), worldAt/captureSwitch (capture playback), worldMarkers and
markersHtml, with node tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>