XML:AKEV

From OniGalore
(Redirected from XML:AGQR)
AKEV : Oni Game Level
XML modding tips
See HERE to start learning about XML modding.
See HERE if you are searching for information on how to handle object coordinates.
See HERE for some typical modding errors and their causes.
XML.png
XML

AISA << Other file types >> BINA

switch to OBD page

Unfinished building-60px.jpg

This page is unfinished. Can you fill in any missing information?
If it is not clear which part of the page is unfinished, ask on the talk page.


Current situation: As AKEV cannot be round-tripped (re-imported) through XML, there is no need to extract it unless it is for research.


AKEV

XML tag Content type Description
<AKEV id="...">
<Points>
<Planes>
<TextureCoordinates>
<Quads>
<QuadTextures>
<QuadCollision>
<Debug>
<Textures>
<BnvNodes>
<BnvSides>
<QuadGroupList>
<QuadGroupId>
<BnvBspTree>
<TransparencyBspTree>
<Octtree>
<BnvAdjacency>
<DoorFrames>
<BoundingBox>
<Min>
<Max>
<Offset_007C>


PNTA

XML tag Content type Description
<PNTA id="...">
<BoundingBox>
<Min>
<Max>
<BoundingSphere>
<Center>
<Radius>
<Positions>
<Vector3>


PLEA

XML tag Content type Description
<PLEA id="...">
<Planes>
<Plane>


TXCA

XML tag Content type Description
<TXCA id="...">
<TexCoords>
<Vector2>


AGQG

XML tag Content type Description
<AGQG id="..."> integer Instance id. Should be 4.
<Quads>
<AGQGQuad>
<Points>
<Int32>
<TextureCoordinates>
<Int32>
<Colors>
<Color> color
Did we overlook the memory for vertex shading on (OBOA) dynamic objects or is that data copied at runtime from the (ONOA) static objects? The door texture name is "DOOR_SB_01".
Example of baking ambient lighting into vertex colors in XSI.
Light test ingame.png

Colors are stored as four-element arrays: R G B [A], which means Red, Green, Blue, and the optional Alpha channel value. Min value: 0. Max value: 255.

This is used for vertex shading.
Vertex shading for moving door parts. According to GPT-5.6 Sol:
Moving door parts do not store independent per-vertex colors.

At level initialization:
1. Door OBOA geometry contains M3GM meshes with positions, normals, UVs, and textures—but no color array (BFW_Object_Templates.h:75, BFW_Motoko.h:1024).
2. ONrLevel_ObjectGunk_GetShade() averages the ARGB corner colors from associated static AGQGs (Oni_Level.c:1152-1216).
3. That single color is stored at runtime in OBJtOSD_Door.shade, then copied to OBtObject.flat_lighting_shade (OT_Door.c:2702-2716, 2570-2596).
4. During rendering, this RGB value becomes the sole ambient light; point and directional lights are disabled (BFW_Object.c:359-376, Oni_GameState.c:4659-4669).

Thus the apparent shading in the proof image (screenshot) is a uniform texture-modulating color derived from nearby AGQG vertex shades, not varying colors stored on the door’s vertices.

    Object type: Shading source
    Static AGQG: Four serialized ARGB corner shades
    Moving door leaf: One runtime average of associated AGQG shades
    Ordinary dynamic M3GM: Draw-time Gouraud lighting from vertex normals

So the closest “storage location” is the runtime fields OBJtOSD_Door.shade and OBtObject.flat_lighting_shade; it is not serialized as door vertex-color data.

How can we re-enable vertex shading for static (class-imported) objects and moving objects (or at least for doors)?

  • As a long-term solution, game assets could also be stored in non-ONI formats that support instant editing of vertex shading.
  • Neo optimized level project files (master XML files) to use his "shared" class system. For now, in order to keep the workflow mostly untouched, we would have to set up proxies in Blender that capture the light data.
    • In XSI it was possible to bake ambient light to vertex colors. It was often said that Blender lacks such a feature. However, with a script, this should also be possible.
    • In a final step, we would need to hex-patch the AKEV*.oni files so that the static meshes (because of class usage) are no longer blank. The slots for vertex shading are always present because the AGQG structure is fixed; we just need to fill them. Fortunately, the engine would then light the linked moving parts automatically at runtime. Tests proved that this can be done. And hex-edited game data is not new to us. Nowadays, such work is relatively easy by connecting an LLM with OniSplit's source code and existing ONI files. That combination is quite effective because it bypasses potentially incomplete wiki documentation or offset differences between official hex-data documentation and how OniSplit actually stores data.
    • The biggest challenge is matching the vertices when the object IDs are no longer identical. This depends especially - varying according to the modding workflow - on when the objects are edited. A programmatic solution can essentially compare the CJBO meshes based on their global coordinates. As additional means of increasing the matching rate, the CJBO type can be compared (see the ObjectId tag), inward-facing faces can be ignored when outward-facing faces have already been found, and partial round-tripping can introduce rounding errors, which can therefore be handled using a tolerance value.
<Flags> flag
DoorFrame (invisible quad that uses the _DOOR_FRAME texture, however, this flag has no effect on the game)
Ghost (pathfinding volume separator, see AKVA, etc.)
StairsUp
StairsDown
Stairs
Triangle
Transparent
TwoSided (make polygons visible from both sides)
NoCollision (no character collision, no particle collision)
Invisible (makes polygons invisible; tip: use two-faced wall for no transition, use one-faced wall for one-way transition)
NoObjectCollision (no particle collision)
NoCharacterCollision (characters can go through polygons)
NoOcclusion
Danger (automatic creation via _marker_danger texture)
Horizontal (slope > 70°, automatic creation)
Vertical (slope < 70°, automatic creation)
GridIgnore (OniSplit will ignore the object when it calculates the pathfinding grids, so the grids will be white)
NoDecals (decals can't be applied to object; doors use this)
Furniture
ProjectionBit0 (automatic creation)
ProjectionBit1 (automatic creation)
SoundTransparent
Impassable
<ObjectId> int32 Object type and object id are merged here into one number. The value is -1 if the quad doesn't belong to an object.
Example 1: If <ObjectId> is 251658333, the converted hex value is (0)f 00 00 5d. With that you get the type 0f = console and the id 5d = 93.
Example 2: If <ObjectId> is 50331739, the converted hex value is (0)3 00 00 5b. With that you get the type 03 = door and the id 5b = 91.

Types:

01 - character
02 - patrol path
03 - door
04 - flag
05 - furniture
08 - particle
09 - powerup
0A - sound
0B - trigger volume
0C - weapon
0D - trigger
0E - turret
0F - console
10 - combat
11 - melee
12 - neutral

Obviously not all object types have corresponding gunk quads. The only object types that are used in ONOA by the original levels are door, furniture, turret, trigger and console. In addition it appears that the engine only searches for door type.

AGQR

XML tag Content type Description
<AGQR id="...">
<Elements>
<AGQRElement>
<Texture>


AGQC

XML tag Content type Description
<AGQC id="...">
<Elements>
<AGQCElement>
<Plane>
<BoundingBox>
<Min>
<Max>


TXMA

XML tag Content type Description
<TXMA id="..."> integer Instance Id. Should be 8.
The TXMA instance stores all textures used by level geometry.
<Textures> - This is an int32 array for <Link> tags.
<Link> link TXMPname


AKVA

XML tag Content type Description
<AKVA id="...">
<Nodes>
<AKVANode>
<BspTree>
<Id>
<FirstSide>
<LastSide>
<ChildBnv>
<SiblingBnv>
<GridXTiles>
<GridZTiles>
<DataOffset>
<DataSize>
<TileSize>
<BoundingBox>
<Min>
<Max>
<GridXOffset>
<GridZOffset>
<NodeId>
<Flags>
<Floor>
<Height>


AKBA

XML tag Content type Description
<AKBA id="...">
<Sides>
<AKBASide>
<Plane>
<FirstAdjacency>
<LastAdjacency>


IDXA (quad group list)

XML tag Content type Description
<IDXA id="...">
<Indices>
<Int32>


IDXA (quad group id)

XML tag Content type Description
<IDXA id="..."> integer Instance ID. Should be 12.
<Indices> - This is an int32 array for the <Int32> tags.
<Int32> int32 Stores an object ID used by BSL commands "env_broken", "env_shade", "env_show" and "env_texswap". Ergo this IDXA should belong to AKEV 2.
Why can IDs appear here multiple times? Most objects are made of multiple triangles/quads. There are as many identical IDs as an object has triangles/quads. When a level gets build, all terrain, buildings and most objects (CJBO) a.k.a. "shared classes" such as furniture and consoles are merged. Through the IDs "individual" objects are still addressable by BSL commands.
"Shared classes" are resources used in OniSplit's level creation workflow. They exist only as links in object collections. While building level linked resources manifest into actual (AKEV) 3D data inside an ONLV*.oni file.

AKBP

XML tag Content type Description
<AKBP id="...">
<Nodes>
<AKBPNode>
<Plane>
<Back>
<Front>


ABNA

XML tag Content type Description
<ABNA id="...">
<Elements>
<ABNAElement>
<Plane>
<Front>
<Back>


AKOT

XML tag Content type Description
<AKOT id="...">
<Nodes>
<Leafs>
<QuadTree>
<GunkQuad>
<Bnv>


AKAA

XML tag Content type Description
<AKAA id="...">
<Elements>
<AKAAElement>
<Bnv>
<Quad>


AKDA

<AKDA id="17" />


OTIT

XML tag Content type Description
<OTIT id="...">
<Nodes>
<OTITNode>
<Children>
<Int32>


OTLF

XML tag Content type Description
<OTLF id="...">
<Nodes>
<OTLFNode>
<PackedGunkQuadList>
<Neighbours>
<Int32>
<PackedPositionAndSize>
<PackedBnvList>


QTNA

XML tag Content type Description
<QTNA id="...">
<Nodes>
<QTNANode>
<Children>
<Int32>


IDXA (gunk quad)

XML tag Content type Description
<IDXA id="...">
<Indices>
<Int32>


IDXA (BNV)

XML tag Content type Description
<IDXA id="...">
<Indices>
<Int32>