Main's model behaviors (every rotation, DoDamage, OnTimer, OnStartup, MoveBackToStart, moves along the model's
local axes), raw terrain reading with scene lookups and scene tools, property model and brick by brick fixes and the
chat server's player count fix, merged onto this branch's structures:
- game messages stay structs; the angular velocity messages join them and the handler sets a message's target
- strips own their speed again and the block names, moves and rotations stay in the shared action table
(PropertyBehaviorActions, which the dashboard's behavior player reads; it now lists rotations too)
- the zone keeps reading its file through ZoneFile and takes the boundaries from it, then loads the raw terrain as main
does; the old dNavigation terrain reader is gone
- the show all response stays a struct and logs a player count mismatch as main does
- the property management component tells models who sent a chat message
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: raw terrain parsing for scene data
Replace old dNavigation/dTerrain raw parser with new Raw module in
dZoneManager. Parse heightmaps, color maps, and scene maps from .raw
files to determine which scene a position belongs to. Build scene
adjacency graph from terrain data and scene transitions.
Adds NiColor type, SceneColor lookup table, eSceneType enum, terrain
mesh generation with OBJ export, and debug slash commands for scene
visualization.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: deduplicate terrain grid lookup logic, remove unnecessary cast
Add IsValidForSceneLookup(), GetSceneIDAtGrid(), and GridToWorldPos()
to Raw::Chunk. Use them in GenerateTerrainMesh, GetSceneIDFromPosition,
SpawnScenePoints, and SpawnAllScenePoints instead of duplicated inline
math. Remove unnecessary static_cast in LoadSceneTransitionInfo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add version < 32 support to raw terrain parser
The parser was only correct for v32 files. For v<32:
- colorMapResolution is width-1, not width
- Color map reads width*width*4 bytes (BGRA per-pixel), not colorMapRes^2*4
- No DDS lightmap
- No texture settings byte or blend DDS
- Scene map: v31 reads (colorMapRes+1)^2 cells with border skip,
v<31 skips 1 byte
- No mesh data
Verified against all 309 .raw files across multiple client versions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: log and reject legacy raw terrain format, clean up ReadRaw API
Log a clear message and throw if the zone uses a legacy raw format
(LUZ version < 30) since no known maps use it. Remove ReadLegacyRaw
and the mapVersion parameter from ReadRaw.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: revert v33 scene field renames to unknown1/unknown2
These fields are skipped by the client in every known build (ptr += 12
and ptr += 4). No client ever reads them into a struct. Keep the
original unknown1/unknown2 names from main.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: load the zone without scene lookups when its raw terrain is missing or unreadable
Log at debug when it parses; build the terrain mesh only for the OBJ export; read the zone name and description only for version 31 and later, as the client does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: look up the scene at a position as the client does, in constant time
Chunk bounds span (width - 1) * scale; the nearest scene map cell is used and the far edge is kept one cell inside. Chunks are indexed by grid cell when they form a grid. Skipping reads instead of seeking, so a cut-off file can't seek past the end. Terrain mesh indices follow the vertex order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: scene point commands take a step and use brick LOTs from the BrickIDTable
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: rename NiColor::ToXYZ to Luminance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: raw terrain reading, scene lookup, scene graph and scene commands
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test: close the OBJ file before removing it so the test passes on Windows
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: keep the zone boundary lines and read the luz scene count as the client does
Each boundary line's destination is read as a map ID and an instance ID into a LWOZONEID. The scene count is a byte before version 37 and a u32 from it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: name the fourth flair colour byte padding
The client never sets or reads it, so it holds leftover memory.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: keep the scene map of version 31 and older raws
These files have a (resolution + 1)^2 scene map, kept in sceneMapLegacy. Version 31 uses its first resolution rows and columns; older versions are all scene 0, as in the client.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor: simplify the raw heightmap size check
The dimensions are capped at kMaxResolution, so the product can't overflow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: remove the scene point spawn commands and send /getadjacentscenes as one message
The spawn commands were only for testing. /getscene and /getadjacentscenes stay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Make again gets a Made by picker, /api/ugc/options lists the processor
choices and default, the settings page has the toolbox_* settings, and
/reprocessproperty takes native or toolbox-blender.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The third ray backend, so every machine has a library for it: Embree on x86
CPUs (embree), HIPRT on AMD and NVIDIA GPUs (hiprt), Embree through SYCL on
Intel Arc and Xe GPUs (embree-gpu).
- CMake option DLU_EMBREE_SYCL (off). dUgcServer/EmbreeSycl is a project of
its own built by a SYCL compiler (DLU_SYCL_CXX; icpx through ONEAPI_ROOT or
the path, or the open source DPC++'s clang++ through DPCPP_ROOT) as an
external project: Embree 4.4 with EMBREE_SYCL_SUPPORT, linked statically and
bound inside (-Bsymbolic, only its C functions exported, so it never meets
the servers' own Embree), and the GPU kernels (nearest hit skipping a ray's
triangle, any hit), into libdlu_embree_sycl next to the servers
- UgcRaysEmbreeGpu loads it the first time embree-gpu is asked for; one GPU for
the process (embree_gpu_device picks it), the workers take turns, the
occlusion rays in batches as for hiprt
- without the build, the library or a supported Intel GPU it falls back to
embree and says why (the UGC server's log at start, --make-model on stderr)
- the option names, the settings page, the dashboard's picker, /reprocessproperty
Verified here: the default build and ctest; the SYCL build with the open source
DPC++ 7.1.0 (compiles, links against oneAPI's libsycl.so.9, exports only its C
functions); on this machine (no Intel GPU) it loads, finds no GPU and falls
back to embree. Not verified: tracing on an Intel GPU (none here).
Check: on a machine with an Intel Arc or Xe GPU and oneAPI, configure with
-DDLU_EMBREE_SYCL=ON and run UgcServer --make-model x.lxfml out embree-gpu;
the UGC tests then compare it with Embree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Embree 4 (always built) replaces the UGC server's own bounding volume
hierarchies (the nearest-hit one and the occlusion rays' any-hit one), with no
fallback to them. ray_backend is embree (default) or hiprt (optional build;
Embree when it can't be used).
Settings, stored options and stats that say builtin still read: it is embree
(UgcRays::Parse, UgcProcessOptions::Parse). The dashboard's picker,
/reprocessproperty and --make-model offer embree and hiprt.
Tests: the backends are compared with Embree (hiprt when built), Embree against
rays whose hits are known, and the clutter's occlusion against what the old
hierarchy worked out (296 vertices summing to 114.5, 26 open, 183 dark); the
pinned model hashes are unchanged with Embree.
Check: ray_backend=builtin in an ini still starts and uses embree; the
settings page offers Embree and HIPRT.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The path tracer that imitated LU Toolbox's Remove Hidden Faces took 17 to 100
times as long as the renders from 42 directions around the model, too heavy to
use. It goes with its settings (hsr_method, hsr_samples, hsr_bounces,
hsr_sample_spacing, hsr_min_points), its side by side tracing for GPUs and its
tests. The renders (UgcRender::VisibleFromAround) remove hidden faces as before
that method existed; their size is hsr_resolution (1024), and the memory
estimate counts their buffers again.
The hidden-face method is no longer a processing option: the dashboard's picker,
/reprocessproperty and --make-model take only the ray backend (the occlusion's)
and denoising. Options stored before (made_options, process_options,
ugc_process_runs, --make-model arguments) that name toolbox or fast still
parse; the word is skipped.
Check: the settings page has no hsr_method or path settings and has
hsr_resolution; /reprocessproperty embree toolbox still works (toolbox
ignored); models made with the defaults keep their hashes (UGC tests).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Staff can make models again with other processing options than the UGC
settings' (ray backend, hidden-face method, denoising) and every make records
what made it, for comparing the options.
- migration mysql 99 / sqlite 82 (ugc_process_options): ugc.process_options
(picked for the next make, cleared once made), ugc.made_options (what made
the current files) and ugc_process_runs (every successful make: options,
wall and CPU time, hidden faces', occlusion's and icon's time, bricks,
triangles before and after)
- IUgc: ResetUgcModelProcessing and ResetPropertyUgcModelProcessing take the
options; PendingModel carries them; RecordUgcModelRun, GetUgcRunSummaries;
list entries have madeOptions and processOptions
- the UGC server applies a job's options over its settings and records the run
- /api/ugc/reprocess takes options ("embree fast oidn"); /api/ugc/options
lists the choices, the settings' defaults and averages per combination
- /reprocessproperty [builtin|embree|hiprt] [toolbox|fast] [off|oidn], any
order, all optional
Check: run the migration on MySQL and SQLite; /reprocessproperty embree fast
on a property, then the models' made_options and ugc_process_runs rows;
/api/ugc/options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/Guilds.md gains what DLU does with the client's guild system: the chat server as the authority, the world <-> chat
packets, the rank rules, the invite and name rules, the slash commands, the dashboard page and what is not done (a
member's name change reaches guildmates only with the next GUILD_DATA; reputation is 0). docs/Commands.md lists the guild
commands, docs/Dashboard.md the Guilds page, the guild names in the Review Queue and guild chat under chat_private.
Check: nothing in game (documentation only).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dashboard.md: what a grant and a deny are, how they combine with GM levels, what can't be granted, who may manage
them (grants_manage, nothing you don't hold, the rank rules), where they are managed, live changes, audit log entries
and the API. Commands.md: how grants and denies apply to slash commands.
Check: the new sections read correctly and the link from Commands.md to Dashboard.md#permission-grants works.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/LiveUpdate.md: how to start one, the order, each kind of instance, the
states, routing, moving players and properties, messages, settings, what a
player sees and the limits. SeamlessTransfer.md, Commands.md and Dashboard.md
point to it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A GM 8 command: every brick built model on the property you are on goes
back to the UGC server's queue. Once all are made (at most 15 minutes),
everyone on the property is sent the new mesh checksums and transferred
back into the same zone and clone, so their game loads the property again
and downloads the new meshes. Swapping a model's mesh in place doesn't
work in the client, so the whole property is loaded again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat: testmap improvements
fixes#1191
removed the force flag because it would only work to let you softlock your character.
tested that taking the lego club door now spawns you at the lego club/ns lego club doors always vs letting you spawn where ever.
tested that a testmap no longer spawns you where you last were in a zone and instead spawns you at the spawn point
inspect allows you to inspect zoneControl and localCharacter now
updated docs with the new info
* Update Entity.cpp
> Added `spawngroup` command
> Recorded some commands that were out of order from least to greatest GM level
> Filled in missing admin levels
> Added alt spellings of commands
> Fixed incorrect GM level of `fly` command from 4 to 6
* feat: reward codes
this is for giving rewards across characters as the did in live.
Tested that the default config works
Tested that all claim codes work
Tested that saving and loading claim codes work
Tested that mail sends correctly
* newlines
* include array
* delete cascade
* newline
* address feedback
* Added cooldown handling
* Made most of the logs hidden outside of debug mode
* removed weird submodule
* kill this phantom submodule
* updated to reflect reviewed feedback
* Added IsCooldownImmune() method to DestroyableComponent
* friggin typo
* Implemented non-pending changes and added cooldown immunity functions to DestroyableComponentTests
* add trailing linebreak
* another typo :(
* flipped cooldown test order (not leaving immune)
* Clean up comment and add DestroyableComponent test
* Re-write AOE behavior for new filter targets
Update Tacarc to use new filter targets
Added dev commands for skill and attack debugging
* Get all entities by detroyable
rather than controllable physics
Since destroyables are what can be hit
* Re-work filter targets to be 100% live accurate
reduce memory usage by only using one vector and removing invalid entries
get entities in the proximity rather than all entities with des comps in the instance, as was done in live
* remove debuging longs and remove oopsie
* address feedback
* make log more useful
* make filter more flat
* Add some more checks to filter targets
add pvp checks to isenemy
* fix typing
* Add filter target to TacArc and update filter target
* fix double declaration
* Some debugging logs
* Update TacArc reading
* make log clearer
* logs
* Update TacArcBehavior.cpp
* banana
* fix max targets
* remove extreanous parenthesesuuesdsds
* make behavior slot use a real type
---------
Co-authored-by: David Markowitz <EmosewaMC@gmail.com>
* breakout gmlevel enum and make it a class
tested that things still work
slash command,
chat restrictions,
packets and serializations
* fix GM level for some slash commands
* fix new use of this enum
* Update README
The README is very out of date, the following changes have been made
- Update what the file tree should look like
- Remove client Avant Gardens Survival script fix
- Update some incorrect commands or commands that were missing packages.
- Add packed client setup instructions
- Add *config.ini setup instructions
- Describe what configs should be modified and what you may want to change
- More detail in the verify step
- Change Account Manager link to Nexus Dashboard
- Remove table of commands and reference Commands.md instead
- Specify that UGCSERVERIP may need to be changed to localhost as well
* Fix Avant Gardens Survival
This addresses the Avant Gardens Survival bug. Squeezing it in with the README changes since it is a small change.
* Remove Locale
* Update README.md
Co-authored-by: Jonathan Romano <jonathan@luxaritas.com>
* Remove dLocale again?
* Saving for the night
* Revert "Fix Avant Gardens Survival"
This reverts commit b1a1ce2d84.
* Update Mission.cpp
* Update README.md
Move comments and add pre-processor define
Update README.md
Update README.md
Update CMakePresets.json
Update CMakeVariables.txt
Update README.md
i love readmes
Update README.md
Update README.md
Update README.md
Update README.md
Update README.md
Update README.md
Update README.md
* Update README.md
Co-authored-by: Daniel Seiler <me@xiphoseer.de>
* Address feedback
* Update README.md
* Update Database.cpp
* Update README.md
* Revert tcp specification
Co-authored-by: Jonathan Romano <jonathan@luxaritas.com>
Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
Co-authored-by: Daniel Seiler <me@xiphoseer.de>
* Mounts -v2
* fix stun state and make comments a bit nicer
* remove extra serilization
* update the char position a bit more correctly
* make vehicles face thr player's direction
* address feedback
* fix compiling for real this time
* removed uneeded check
* Added documentation for all available commands
* Adjust formatting, removing backtick characters
* Replace HTML tables with Markdown tables
* Formatting changes
* Suggestions from @sersorrel in #402 and other minor edits
* Add detailed usage for /inspect
(thanks to @sersorrel for this information, in discussion of #402)