Skip to content

ReyEngine v0.4.7-beta

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Sep 22:29
· 119 commits to main since this release

A release about putting your own characters in a map, and about a map with everything switched on. Every mob breathing and every particle playing used to be the slow way to look at a map; the frame no longer stops when the camera swings, the cinematic export no longer freezes the window, and the inspector shows an asset where you look for it. The Character Editor catches up with the game on what a champion does while it stands there — its idle effects, its show-and-hide, its chromas — and gets its map back under Direct3D 11, lit the way the old client lit it. And two things now look after themselves: a map skin you forced survives the next patch, and the hash tables stay current.

Added

  • Character Creator: an old character folder becomes a prop your map can place. Tools ▸ Import character folder… reads a folder of any age — its mesh, its skeleton, its animations and its texture — says what era every file is in, and brings the outdated ones to the form the game writes today: simple skins to 4.1, the pre-2015 rig to the current one, and animations to version 5, which the toolkit this editor builds on can read but never write. It then writes the three bins a placed character needs, in the shape Riot's own scenery props have, stages everything into the open map's package, and puts the prop down where the gizmo is. A mesh whose bones the skeleton does not have is refused rather than placed folded; an animation that moves none of that skeleton's joints is left out and said so, rather than shipped silent.

  • Add prop to map. Tools ▸ Add prop to map… lists every character the open map's package already carries — the camps, the turrets, anything you imported — and places one as scenery at the gizmo, with the idle it should play. A placed prop draws and animates, and nothing in game can target it. Characters you make with the Character Creator appear in this list as soon as they are staged.

  • The particle preview can carry an effect the way the game does. A particle file describes emitters and says nothing about where the effect goes: a missile is a missile because a spell flies it, not because of anything in the bin. So the preview sat everything at the origin, which shows a missile as a puff standing still and a trail with nothing to trail behind. The preview now has a rig. Still leaves it where it is. Burst starts the whole run over as soon as it ends. Missile flies it in a straight line at a real speed and stops it emitting where it lands, the way the game does. Trail circles it so a ribbon has a path to lay itself along. There is a height, a switch to replay the run, a switch to stop the effect halfway through so its teardown plays without holding Stop, and a seed - the whole of a run's randomness, so the same number gives the same run twice and a new one shows the effect playing differently without editing it. The rig opens on a guess from the system's own name, and says why it guessed, because the name is right about nine times in ten for a missile and wrong in the two ways that matter: a dash and a recall are written like one.

  • The preview rig comes from the game, not from a guess, when the effect belongs to a champion. A spell record names the effect it flies and carries that ability's own speed, so the preview no longer has to read the effect's name and hope. Open a champion's particles and a missile flies at the speed the ability really uses; an effect a spell plays on whatever it hit, or one a buff hangs on a bone, is told apart and stands still with the bone named. The panel says which of the two you are looking at, so a guess is never mistaken for an answer. Nothing outside a champion has a spell to ask, so a map's effects keep the name guess as before.

  • The particle editor has the shape a particle editor has. Five panes: the system list down the left, the emitters across the middle, the details on the right, and the curve editor beside the 3D view along the bottom, both running the full width of the window. The curve plot and the preview used to share the middle column under the emitter cards, which left the plot about a third of the window wide and the preview smaller than a single emitter card, while the two narrow panes beside them took the full height. Every pane says what it is and no splitter can collapse one into nothing. The rig sits at the foot of the details pane rather than over the 3D view, so the whole preview is free to look at and orbit.

  • The curve editor edits. The plot beside the 3D view used to be only a picture of the keys, with the numbers typed into a list next to it. Now you can drag a key to move it, double-click the graph to add a key where you clicked, and press Delete to remove the selected one. A key cannot pass its neighbours, and holding Shift while dragging keeps it on one axis. The wheel zooms, Ctrl zooms time only, Shift zooms the value only, and a right-drag pans. You can hide a colour curve's channels one at a time, or solo one with Ctrl-click, so you can edit red without grabbing green. A drag moves the key on screen while you hold it and applies once when you let go, so the effect is rebuilt once per drag, not at every pixel. A read-only file shows its keys as rings that cannot be picked up. The typed list stays, for when you need an exact number.

  • The champion window can rig an effect too. Picking one of a skin's effects by hand used to sit it still at its anchor, with nothing to start it over and no way to see its teardown. It now takes the same rig the particle editor has, and it takes it from the game: an effect a spell flies gets flown at that ability's real speed, and an effect the skin hangs on a bone is hung on that bone - which this window can do and the particle editor cannot, because this one has the champion. A cast composite and a clip effect are left alone; both already move better than a rig could.

  • A forced map skin survives the patch. The Map Skin Switcher's result used to go through the Patch Update Wizard like any other bin: diff it against the original it was made from, re-apply the differences onto the new original. That is the right thing for a hand edit and the wrong thing for a rule. Riot adds and removes map skin slots between patches — 16.17 brought a Hall of Legends slot, 16.18 took it away again — and a slot that did not exist when you forced the map cannot be in the diff, so it arrived as Riot shipped it, the game picked the seasonal slot, and the map you forced was gone. The switcher now records what you asked for in the project file — which map, which environment every slot is routed through, whether the turret, minion and nexus skins came along — together with a copy of that environment. At update time the wizard does the switch again on the new original, new slots included, and merges only the edits the recipe does not explain, so a conflict it reports is a real one. If Riot stops shipping the environment you forced, the recorded copy is applied and the report asks for a look in game. A map bin made before this existed gets its recipe worked out from the bin itself the first time the wizard meets it; one that cannot be worked out — a bin edited by hand after the switch — is merged as before, and running the switcher once makes it remembered from then on.

  • Hash tables and meta classes keep themselves current. Names for hashed paths come from CommunityDragon's lists or Mimir's tables, and the class schema behind the bin editor from LeagueToolkit, and all three were updated only when you remembered to ask. At startup the editor now fetches a newer Mimir release — or the CommunityDragon lists, whichever this install already uses — and a newer meta-class database, and re-resolves the open project. When nothing is new it costs one request each: the meta database is asked with the tag of the copy on disk and answered unchanged, and a CommunityDragon sync skips every file whose content hash the last sync recorded. Preferences ▸ Updates has the switch, on by default; off, Tools ▸ Sync is what it was. Mimir releases are kept one folder each, an unchanged table is reused from the previous release rather than downloaded again, and older releases are removed once nothing reads them — five of them, some 300 MB, used to sit beside each other with nothing ever clearing them.

Improved

  • A field you add is editable straight away. Adding one from the schema wrote it into the bin and then showed nothing to set it with, so the value you came for was there and out of reach until the file was opened again. The row now appears the moment the field does. Texture-valued fields can be added too - emissive, gloss and reflection maps - at the empty link the game already assumes.

  • The skin's own settings are editable. A character with no material draws from the skin's own block, and the editor showed only its diffuse. Everything else that block carries is now listed and editable - self-illumination, fresnel colour and strength, reflection opacity, gloss, emissive, brush alpha, cast shadows, skin scale - and any of the 43 the schema declares can be added at the value the game already assumes, so materialising a setting and changing it stay separate steps.

  • A character's submesh can be given a material. A character material is optional: Riot's scenery characters ship none at all and draw from the skin's own block, and so does an imported one - which means there was nothing to change the shader of. Each submesh in the character window now offers to author one, starting from the texture that submesh already draws with so nothing changes appearance, on a skinned shader that asks for nothing else. From there its shader, samplers and parameters are ordinary edits.

  • A placed prop can be moved. Mobs and props have been drawn in the map since the viewport learned to skin them, but the gizmo never touched one: selecting a prop showed no gizmo, and the editor had nowhere to keep a moved position. A prop now moves, turns and scales like every other placement, in one undo step, with its coordinates ticking in the panel as you drag, and the moved matrix is what gets written. A prop you did not move still writes nothing, so Riot's own placements keep the transform they shipped with.

  • Animated props cost a fraction of what they did. The pose of a placed mob is computed once per skin, into buffers that are reused every frame instead of thrown away (on the jade map: 322 KB of garbage per frame gone), only for skins with a placement within the camera's range, and no more often than 30 times a second for an idle. In the OpenGL viewport the vertex pass — the whole of a 60 fps budget for the jade map's 21 animated skins — now runs on every core: 12.6 ms became 1.8 ms, and at 30 Hz under a 60 fps frame under 1 ms on average. The Direct3D 11 status line says where the frame's CPU went: props, particles, and how many systems are still warming up.

  • A camera swing no longer stalls on particles. A system that comes into view is warmed to its steady state, as before, but a few systems per frame under a time budget instead of all of them in the frame they appear; the effects fill in over a handful of frames rather than the frame stopping for all of them.

  • Cinematic Capture keeps the editor usable while it exports. Frames render between the editor's own work, the PNGs are encoded on the other cores behind the renderer, the live viewport flies the shot as it is captured, and both the Cinematic window and the status bar count frames rendered and written. Cancelling stops the rendering and finishes the frames already rendered, so a sequence never ends in a truncated file.

  • The asset card is on the Overview tab. The identity card, preview, details and note that sat above the Overview / Materials / Shaders strip are inside Overview now, for every asset, so the strip and the card no longer compete for the top of the panel.

  • The Character Editor plays what the game plays while a champion stands there. Measured against LTK Manager's character viewer, and closed one gap at a time. A skin's idle effects — Lux's wand glows, Thresh's lantern — are read as the list they are and mounted on their bones from the skin's own bin: a Thresh skin reads 1,047 of those records where 490 were reached before, and two glows that share one effect and differ only by bone both play. A clip's particle events fire on the animation clock — their start delay in the clip's own frame seconds, an end time, one effect per event with its own bone and target bone — and an event that kills an effect stops it instead of spawning a second copy. Show-and-hide is a timeline, not a union applied from frame 0: Kayn's Transform_Assassin shows two submeshes and hides one at frame 114, and 194 of Aatrox's clips carry more than one such event. The tick you set on a submesh by hand is a layer of its own, applied last, so changing clips no longer resets it; a clip's authored tick duration is honoured (223 of Aatrox's 1,353 clips set one); an effect attached to a bone stays on the bind pose until the clip moves it; and a beam's far end follows its bone on both renderers.

  • The Character Editor's map, on both renderers. Two environments — Dominion and Twisted Treeline — offered by the setup wizard and by Settings, installed from the packs and checked for the room file instead of trusting the extraction. Twisted Treeline no longer inherits Dominion's hand-tuned hero-shot placement (6,400 units off, turned around). Unloading an arena puts the configured map back instead of leaving the viewer in empty space, and loading another champion no longer resets the map you picked. Under Direct3D 11 the map drew white, and behind the white was a flat diffuse copy of it, because that renderer had no way to draw a legacy level. It has one now: the four-way ground blend, the height blend, the composite colour atlas, vertex light, the level's torches, cutouts and blends, with the material math taken from the old client's own shader source — so both renderers draw the same room, and the MAP BACKDROP card's sliders drive both.

Fixed

  • The shader list offered shaders the material could not be drawn with. The picker listed all 350 shaders the client ships, whatever the material was for. Measured across the installed game, that is not a choice the data supports: every one of 5,870 map materials is on a static-mesh shader, and 2,235 of 2,237 character materials are on a skinned-mesh one. The two are fed by different draw paths, so crossing them makes the game report a missing shader constant and draw nothing. The picker now lists the family the material is drawn with, plus anything the file itself already uses, and says which family it is showing. Picking from the other family is still allowed, since two shipped character materials really are on a UI shader, but it is never silent - and a file that already carries a crossed shader says so when it is opened.

  • The skybox came and went during a cinematic export, and the window froze. From the second frame on, the export was rendering into the Direct3D 11 context from a thread-pool thread while the live viewport drew on the UI thread — two threads in one immediate context. Every frame now renders where the viewport does.

  • Particles with no texture drew a white square, or a placeholder that is not in the game. An emitter can leave its texture unset, and the game answers that with a single transparent pixel: the emitter contributes nothing. The editor had one answer where the game has three. The particle preview window bound nothing at all, which let an opaque white pixel through and drew the effect as a hard white card; both map viewports substituted the soft placeholder dot instead, so a few hundred emitters that were never meant to be seen showed up as dots. A texture that the editor was asked for and could not find still shows the placeholder, because that one is the editor's own failure and worth seeing - and the preview window shows it too now, instead of the white card. The build report says how many emitters named no texture, so an effect that was never drawn cannot be mistaken for one that went missing.

  • A child effect could be spawned from the wrong emitter. A system's emitters can each carry their own child systems, and the list of them is kept in the order the file writes the emitters. The playback loop read it by the emitter's position in the running simulation instead, and those two stop agreeing as soon as one emitter is skipped - which happens in most systems, because an emitter that draws nothing is not simulated. The effect that played was whatever belonged to a different emitter, or none at all.

  • An effect meant to lie on the ground drew on top of everything. Emitters carry a layer flag and a pass number, and the editor sorted on the pass alone. The game does not: an emitter marked as ground layer draws in a list of its own that runs before everything else, and the pass only orders emitters inside one list. So a glow authored late in the pass order covered the rocks and props it is supposed to sit under. Both viewports now draw the ground layer first. The particle editor's own preview had no draw order at all before this and now has the same one. An emitter that writes or reads a stencil mask keeps its authored position, because moving one of those past its partner makes it disappear rather than reorder, and the field is no longer marked in the editor as having no effect on the preview.

  • The map's Direct3D 11 viewport ignored the draw order artists author. Emitters carry a pass number that says what layers over what, and this viewport discarded it: it drew particles in the order it happened to build them, which is by placement and then by however the file lists the emitters. The line that looked like it sorted them runs after the work it would have sorted, so it only ever decided how the particle budget is divided. Particles are now handed to the renderer in draw order, with beams, trails and mesh emitters ordered against the billboards rather than each in their own pile.

  • Effects meant to draw over everything were cut into by the ground. An emitter can be marked to ignore the depth buffer, which is how a decal painted on terrain it is coincident with, a stencil-masked shape and a heat haze all avoid being sliced by the geometry they sit on. Both viewports tested depth on every particle regardless. Two in five emitters in the game carry that mark, and they now draw the way they were authored to. Only the test changed; whether a particle writes depth is up to its blend mode.

  • Mesh particles ignored the depth push their artist authored. An emitter can ask to be pushed away from the camera or pulled toward it, which is how a decal wins against the ground it lies on. The two viewports disagreed: the Direct3D 11 one runs Riot's own shader and has always done it, and the OpenGL one only did it for flat sprites. 14,451 mesh emitters in the game author that push and 92% of them author it negative. Also, a particle's spin over its life was read from a different axis than the angle it starts at, so one of the two was always being ignored.

  • A dissolve map wrapped the wrong way, and two effects drew stages the game does not. An erosion map carries its own setting for what happens where the coordinate runs off it, and the coordinate runs off constantly because it carries the sprite's scroll. Neither viewport read that setting: four fifths of the effects in the game leave it at mirror and both were sampling it as a repeat. Separately, an emitter that locks its alpha is drawn by the game through a shader that has no dissolve stage and no soft-particle fade at all, and the editor was compiling both for it - 3,390 effects were showing something the game does not draw.

  • Flipbooks looped back to the wrong cell, and the scroll clamp held the wrong thing. A particle sheet can start its animation partway in, and the game loops it back to that starting cell; the editor looped it back to the sheet's first cell, dropped the start altogether when the start was random, and ignored it on a single-frame sheet - so a torch meant to show one cell of its sheet showed the first, on nearly three thousand effects. Separately, the scroll clamp holds a sprite's own birth scroll one cell out; the editor clamped the whole sprite, zoom and spin included. Both viewports now scroll the way the setting says, and what holds a sprite at its edge is the sprite's texture address setting, which neither viewport read before - and whose meaning the editor had wrong, since 2 is a clamp and not a mirror. The Direct3D 11 viewport and the particle preview now apply a sprite's offset, spin, zoom, flips and its particle and emitter scrolls, none of which they did before; the preview applied no scroll at all. A flip now comes after the scroll, so a flipped sprite scrolls the other way, as in game. Scrolls on a multi-cell sheet now move a cell at a time at their authored rate, which is slower than before on those sheets.

  • Half the particles in the game blended the wrong way. A particle's blend mode is a number, and the editor had been guessing what each number means from how things looked in its own viewport. The game's own names for them settle it, and so does the art authored under each: mode 1, the most common value in the game, is ordinary transparency, and the editor was adding it as light - over 600,000 effects, which washed out smoke, shadows and every dark layer. Mode 3 is solid and hides what is behind it, mode 5 is premultiplied, 6 and 7 keep the darker or the lighter of the two, and additive particles now fade with their colour the way the game's do. Both viewports use one table, and the draw order gains the two keys that were waiting on it. An effect that sets no alpha cutoff uses the game's default of 5, so the transparent border of an additive sprite no longer draws. Converting an old particle file no longer writes mode 1 for a sprite whose blend could not be read; it leaves the game's additive default.

  • A character placed on a map never appeared in game. The Character Creator and Add prop to map wrote the placement and nothing else, but the game only preloads the characters the map's own bin lists. One that is placed and not listed is drawn as if it were a static mesh, which shows up in the game log as a shader it cannot find and a missing WORLD_MATRIX, and the character is not there. Placing a character now also adds it to the map's character lists, in the list that already holds the map's other scenery, together with the small Character entry every listed character has. Every character on the map is checked each time, so one placed before this change is added the next time anything is placed.

  • A placed character played the wrong idle. A placement can name the idle its character plays; the writer never wrote it and the extractor never read it, so a placed character guessed at its skin's first idle clip. The yonkey on Summoner's Rift authors an idle that is not its first, and previewed doing the wrong thing. The placement's own idle is written, read and played, with the guess kept only for a placement that names none.

  • A chroma opened as the skin it recolours. Lillia's skin 49 showed skin 46. A chroma ships no mesh of its own — its bin names the base skin's mesh, and its own textures, materials and particles — and every read the Character Editor made worked the skin's bin out from the mesh's folder. That rule is wrong for most skins, not a few: across all 174 champion WADs, 11,304 of 14,749 skin bins name another skin's mesh, 7,020 of them chromas. The chosen bin now travels with the mesh through every read — textures, render state, the Direct3D 11 scene, effects, idle effects, submesh rules, voice events, the material editor — so a chroma looks like itself and material edits on one preview again. The picker lists chromas under their base skin with a chroma badge, and the header names the skin beside the mesh.

  • Point lights were capped, and the sun lit from below. Direct3D 11 stopped reading a level's light file at 256 lights; Dominion ships 462, so 206 torches lit nothing. Both renderers now take up to 1,024. The sun was worse. The OpenGL renderer wants the direction toward the sun and reads a zero direction as "use my own default sun", so Dominion's Bright slider did nothing and Twisted Treeline's night sun, authored as the direction the light travels, lit the map from below; Direct3D 11 read both literally and drew Dominion flat. One resolver now feeds both renderers: Dominion is lit by the sun its level file authors — built in, because the backdrop packs ship without that file — the way the old client lights a level with no colour map, and the torches start off where the level bakes its pools into the vertex colours: on Dominion, of 1,027,174 vertices, the 267,279 outside every light's reach are exactly black, so the pools are already in the mesh. The defaults apply once per map rather than on every skin load.

  • Sync failed: Object reference not set to an instance of an object. After every hash sync in a folder project, once the tables had already loaded: the step that applies the new names re-resolved the single-WAD archive a folder project does not have. The project's WAD mounts are re-resolved in place and the tree rebuilt instead, so the names arrive without reopening anything.