XML:ONLV: Difference between revisions

From OniGalore
Jump to navigation Jump to search
m (the "twosided" paradox)
m (tested env_texswap; removed some old stuff)
Line 1: Line 1:
{{finish}}{{update}}
{{finish}}{{update}}
;Todo list
* add xml header to this page
* more notes on the shared folder
* test import with prefix-ed files in shared folder
* tips with cutscene charas: sync pelvis OBANs and partner TRAM
* examine low doors/openings: atm sliding under low objects don't seem to work
* more notes on BNV, linked xml, and exported xml files




__TOC__
==Level releases, forum threads and wiki pages==
Custom levels that have been created so far:
Custom levels that have been created so far:
* [http://oni.bungie.org/community/forum/viewtopic.php?id=2357 Old China]
* [http://oni.bungie.org/community/forum/viewtopic.php?id=2357 Old China]
Line 18: Line 29:
* [http://oni.bungie.org/community/forum/viewtopic.php?pid=37252#p37252 "Modding Existing levels - Beta" ("Moveable furniture" post)]
* [http://oni.bungie.org/community/forum/viewtopic.php?pid=37252#p37252 "Modding Existing levels - Beta" ("Moveable furniture" post)]


wiki pages about levels:
Wiki pages about levels:
* [[AE:Levels]]
* [[AE:Levels]]
* [[AE:Lightmapping_levels]]
* [[AE:Lightmapping_levels]]
* [[SketchUp_tutorials_and_tips|SketchUp tutorials and tips]]
* [[SketchUp_tutorials_and_tips|SketchUp tutorials and tips]]


Free texture resources
* [http://www.tutorialsforblender3d.com/Textures/Textures_index.html various game textures]
* [http://forums.epicgames.com/threads/603122-Remus-high-resolution-skydome-texture-pack skies and objects of the solar system]
* [http://blenderartists.org/forum/showthread.php?224065-New-High-resolution-sky-pack-for-Blender skies] <!-- (http://www.wuala.com/Olson/Photos/Optikz_360_Skies/) -->
* [http://blenderartists.org/forum/showthread.php?24038-Free-high-res-skymaps-%28Massive-07-update!%29 skies]
* [http://www.cgtextures.com/ CG Textures for 3D]
==Level import with onisplit [http://mods.oni2.net/node/38 0.9.82.0]==
'''General information on level import'''
* the import doesn't work with empty skybox tag; <Sky>clear</Sky> helps here (or maybe onisplit just wants a name and doesn't care if the resource really exists?)
* triangle limit: ca. 520.000 (500.000 to be on save side)
* actually this is not about the import but when the triangles are packed too tight then the cam will look at too many of them and glitches appear: the visible GQs limit is ca. 16.000, sooner or later higher numbers will cause render bugs and call BSL message "Exceeded max visible GQs ''number''" (you can decrease the gs_farclipplane_set value to avoid that problem)
* also, keep in mind that characters are visible ''only'' within 4099|4099|4099 and -4099|-4099|-4099 world units
* geometry stops at ca. X=4228|Z=4228 and -4228|-4228 (height not tested)


For praxis information see: "Creating the Lair - A level tutorial" link.


'''Demo files'''


==Level import with onisplit [http://mods.oni2.net/node/38 0.9.82.0]==
Demo files can be downloaded [http://dl.dropbox.com/u/1869/lab.zip here].
Demo files can be downloaded [http://dl.dropbox.com/u/1869/lab.zip here].


Line 53: Line 78:




===the master xml file===
===The master xml file===
The '''master xml file name''' determine the '''bsl folder name''' and the '''AKEV and ONLV file name''' in the output folder.
 
;trimmed master file "lab.xml" from the demo:
{| class="wikitable" style="float:right"
{| class="wikitable" style="float:right"
|
|
Line 62: Line 90:
* Character.xml with player
* Character.xml with player
|}
|}
 
<?xml version="1.0" encoding="utf-8" ?>
The '''master xml file name''' determine the '''bsl folder name''' and the '''AKEV and ONLV file name''' in the output folder.
<Oni>
    <Level SharedPath="../shared">
        <Environment>
            <Model>
                <Import Path="env/lab_env.dae"/>
                <Import Path="env/lab_bomber_window.dae"/>
                <Import Path="env/lab_motorcycle.dae">
                    <Node Id="motorcycle">
                        <ScriptId>9</ScriptId>
                        <GunkFlags>NoCollision</GunkFlags>
                    </Node>
                </Import>
            </Model>
            <Rooms>
                <Import Path="env/lab_bnv.dae"/>
            </Rooms>
            <Textures>
                <Texture Name="GOO">
                    <Format>bgra4444</Format>
                    <GunkFlags>NoCollision</GunkFlags>
                    <Image>env/images/GOO.tga</Image>
                </Texture>
            </Textures>
        </Environment>
        <Sky>sunset</Sky>
        <Objects>
            <Import>Character.xml</Import>
            <Import>Furniture.xml</Import>
            <Import>TriggerVolume.xml</Import>
            <Import>Physics.xml</Import>
        </Objects>
        <Films>
            <Import>films/BomberKonRun01.xml</Import>
            <Import>films/BomberKonRun02.xml</Import>
        </Films>
        <Cameras>
            <Camera Path="cameras/BomberCam01.dae">
                <Animation Name="BomberCam01"/>
            </Camera>
            <Camera Path="cameras/BomberCam02.dae">
                <Animation Name="BomberCam02"/>
            </Camera>
        </Cameras>
    </Level>
</Oni>




====shared folder====
====Shared folder====
The master xml file can link to other xml files, most of them are [[OBD:BINA/OBJC#OBJC_types|BINACJBO]] files. The file type gets declared inside the file, so the file name itself doesn't has to contain the type. Ergo, "BINACJBOCharacter.xml" can be given a simpler name like "Character.xml".
The master xml file can link to other xml files, most of them are [[OBD:BINA/OBJC#OBJC_types|BINACJBO]] files. The file type gets declared inside the file, so the file name itself doesn't has to contain the type. Ergo, "BINACJBOCharacter.xml" can be given a simpler name like "Character.xml".


Line 117: Line 189:




=====breakable objects with BSL recognition=====
=====Breakable objects with BSL recognition=====
Broken env objects can be recognized by bsl command ''env_broken (ID_1, ID_N)''. However, this whole thing requires additional code to work.
Broken env objects can be recognized by bsl command ''env_broken (ID_1, ID_N)''. However, this whole thing requires additional code to work.


Line 211: Line 283:




=====texture exchange=====
=====Texture exchange=====
Not tested.
BSL command [[BSL:PC_vs._Mac_Comparison_(table)|supported]] for PC and Mac:
 
source: ([[OBD:IDXA_AKEV_2]])
 
BSL command [[BSL:PC_vs._Mac_Comparison_(table)|supported]] by PC and Mac:
: env_texswap ID texture
: env_texswap ID texture


Line 391: Line 459:




==Level import with onisplit 0.9.68.0==
(This section refers to the last version of onisplit v0.9.68.0, no others.)
Levels can be created with a xml master file. The name of that file determines the BSL folder name (doublecheck this later).
onisplit -create:level onis master.xml
Onisplit can use already created *.oni files inside the classes folder, however not all file types can be used.
Ignored file types:
* CONS
* OBAN
* OFGA
* TXMP
* ?


Allowed file types:
==Exported Oni Level (ONLV*.xml)==
* M3GM
* ?
 
The xml master file links to dae and other xml files. Its used by onisplit to create *.oni files of ONLV, AKEV, TXMP and the object collections.
 
'''example of master.xml'''
<?xml version="1.0" encoding="utf-8" ?>
<Oni>
    <Level SharedPath="../classes">
        <Environment>
        <Model>
            <Import>level.dae</Import>
        </Model>
        <Rooms>
            <Import>level_bnv.dae</Import>
        </Rooms>
        <Textures>
            <Import>textures.xml</Import>
        </Textures>
        </Environment>
        <Sky>grimmnight</Sky>
        <Objects>
        <Import>Objects.xml</Import>
        <Import>BINACJBOCharacter.xml</Import>
        <Import>BINACJBODoor.xml</Import>
        <Import>BINACJBOFlag.xml</Import> 
        <Import>BINACJBOTriggerVolume.xml</Import>
        <Import>BINACJBOConsole.xml</Import>
        <Import>BINACJBOFurniture.xml</Import>
        <Import>BINACJBOParticle.xml</Import>
        <Import>BINACJBOPatrol Path.xml</Import>
        <Import>BINACJBOPowerUp.xml</Import>
        <Import>BINACJBOTurret.xml</Import>
        <Import>BINACJBOTrigger.xml</Import>
        <Import>BINACJBOParticle.xml</Import>
        <Import>BINACJBOSound.xml</Import>
        </Objects>
    </Level>
</Oni>
 
'''example of textures.xml'''
 
<GunkFlags> should be AGQG flags of [[OBD_talk:ONLV#AKEV:_Akira_Environment|AKEV]], also listed at "onisplit -help enums"
 
<?xml version="1.0" encoding="utf-8" ?>
<Oni>
    <Textures>
    <Texture Name="china_lava">
            <GunkFlags>NoCollision</GunkFlags>
            <Format>RGBA</Format>
            <Image>china/TXMPchina_lava.jpg</Image>
        </Texture>
    </Textures>
</Oni>
 
 
'''example of Objects.xml'''
 
<Geometry> holds a OFGA file linking to M3GM file(s)
 
<Flags> should be OBOA flags of [[OBD_talk:ONLV#ONLV:_Oni_Level|ONLV]], also listed at "onisplit -help enums"
 
<Physics> should be OBOA physics flags of [[OBD_talk:ONLV#ONLV:_Oni_Level|ONLV]], also listed at "onisplit -help enums"
 
<?xml version="1.0" encoding="utf-8"?>
<Oni>
    <Physics>
<Object Name="single_heli_rotorblades_center">
                <Geometry>heli_rotorblades</Geometry>
                <Animation>single_heli_rotorblades_center</Animation>
                <Flags>InUse</Flags>
                <Physics>Animated</Physics>
                <ScriptId>1</ScriptId>
                <Position>800 600 2420</Position>
                <Rotation>-0.07206057 0.656310439 -0.06319542 0.7483784</Rotation>
                <Scale>3.69</Scale>
      </Object>
    </Physics>
</Oni>
 
 
'''additional information'''
* the import doesn't work with empty skybox tag; <Sky>clear</Sky> helps here (or maybe onisplit just wants a name and doesn't care if the resource really exists?)
* triangle limit: ca. 520.000 (500.000 to be on save side)
* actually this is not about the import but when the triangles are packed too tight then the cam will look at too many of them and glitches appear: the visible GQs limit is ca. 16.000, sooner or later higher numbers will cause render bugs and call BSL message "Exceeded max visible GQs ''number''" (you can decrease the gs_farclipplane_set value to avoid that problem)
* also, keep in mind that characters are visible ''only'' within 4099|4099|4099 and -4099|-4099|-4099 world units
* geometry stops at ca. X=4228|Z=4228 and -4228|-4228 (height not tested)
 
 
==ONLV: Oni Level==
{| border=0 cellspacing=20 cellpadding=0 style="float:right"
{| border=0 cellspacing=20 cellpadding=0 style="float:right"
| skybox file ONSKafternoon<br>[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/ONSKafternoon.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/ONSKafternoon_tn.png]
| skybox file ONSKafternoon<br>[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/ONSKafternoon.png http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/ONSKafternoon_tn.png]
|}
|}


file structure
File structure


* ONLV instance
* ONLV instance
Line 528: Line 491:




'''flags in the <OBOAObject> section'''
'''Flags in the <OBOAObject> section'''


these are also used for the physics.xml file
These are also used for the physics.xml file
: '''<Flags>'''
: '''<Flags>'''
:: <!-- None -->
:: <!-- None -->
Line 649: Line 612:




==AKEV: Akira Environment==
==Exported Akira Environment (AKEV*.xml)==
Somehow I would like to have the AKEV and ONLV information on one page (like the sound stuff on SNDD). Let's see how this turns out.
Somehow I would like to have the AKEV and ONLV information on one page (like the sound stuff on SNDD). Let's see how this turns out.


Line 731: Line 694:




===links to free texture resources===
==Ideas to test out==
* [http://www.tutorialsforblender3d.com/Textures/Textures_index.html various game textures]
None ATM.
* [http://forums.epicgames.com/threads/603122-Remus-high-resolution-skydome-texture-pack skies and objects of the solar system]
* [http://blenderartists.org/forum/showthread.php?224065-New-High-resolution-sky-pack-for-Blender skies] <!-- (http://www.wuala.com/Olson/Photos/Optikz_360_Skies/) -->
* [http://blenderartists.org/forum/showthread.php?24038-Free-high-res-skymaps-%28Massive-07-update!%29 skies]
* [http://www.cgtextures.com/ CG Textures for 3D]
* '''''to be expanded'''''
 
==ideas to test out==
===seamless, individual ground textures===
{| border=0 cellspacing=20 cellpadding=0 align=right
| screenshot from Aion:<br>individual textures side by side<br>[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/Aion.jpg http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/3D_modding/Aion_tn.jpg]
|}
 
Could be achieved by breaking the ground mesh into the single polygons and then 3D paint them. The amount of hand work (breaking, applying a material, UV, ...) would make everyone go crazy so some scripting would be needed to reduce the work to a minimum. Mod Tool supports VBS, python and java script. The script could be bound to two buttons: one for breaking everything, another for breaking only a selection of polygons. Mudbox doesn't seem to support any scripting so the scene would need to get transfered back to Mod Tool (easier with the retail/student version). Mod Tool seems to have a buggy texture export. I was able to get only png images and those gets their black parts as alpha exported. So here we need extra caution. A script in PS could add a black layer to each image and then do the final texture export.
 
A bunch of links to scripting pages:
* http://softimage.wiki.softimage.com/sdkdocs/script_editor_RunningScripts.htm
* http://www.adobe.com/devnet/photoshop/scripting.html
* http://matthiasschuetz.com/photoshop-eigene-scripts-und-panels
* http://www.tutorialized.com/view/tutorial/How-to-apply-an-action-to-multiple-images-using-scripts/75340
 
 
===pathfinging on uneven ground===
It would be ridicules if Oni don't allow AIs to run over a hill. If one ramp is okay, why not two ''ramps'' or more in a row/next to each other. The idea simply deserves to become double-checked.




==ideas that has been tested==
==Ideas that has been tested==
===sky dome - it's a fail===
===Sky dome - it's a fail===
{| border=0 cellspacing=20 cellpadding=0 align=right
{| border=0 cellspacing=20 cellpadding=0 align=right
| sky box<br>[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/ugly_skybox_lines.jpg http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/ugly_skybox_lines_tn.jpg]
| sky box<br>[http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/ugly_skybox_lines.jpg http://i305.photobucket.com/albums/nn207/unknownfuture/Oni_Galore_Images/XML_modding/ugly_skybox_lines_tn.jpg]
Line 795: Line 735:




==ideas for onisplit==
==Ideas for onisplit==
Neo might update OniSplit so that it is searching specific strings in object names of a dae level file.
Neo might update OniSplit so that it is searching specific strings in object names of a dae level file.



Revision as of 15:58, 27 February 2013

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.

Aged parchment-60px.jpg

This page contains information that is out of date.
Please update this information to reflect where the community is at today.

Todo list
  • add xml header to this page
  • more notes on the shared folder
  • test import with prefix-ed files in shared folder
  • tips with cutscene charas: sync pelvis OBANs and partner TRAM
  • examine low doors/openings: atm sliding under low objects don't seem to work
  • more notes on BNV, linked xml, and exported xml files



Level releases, forum threads and wiki pages

Custom levels that have been created so far:

OCF threads about level creation:

Wiki pages about levels:

Free texture resources


Level import with onisplit 0.9.82.0

General information on level import

  • the import doesn't work with empty skybox tag; <Sky>clear</Sky> helps here (or maybe onisplit just wants a name and doesn't care if the resource really exists?)
  • triangle limit: ca. 520.000 (500.000 to be on save side)
  • actually this is not about the import but when the triangles are packed too tight then the cam will look at too many of them and glitches appear: the visible GQs limit is ca. 16.000, sooner or later higher numbers will cause render bugs and call BSL message "Exceeded max visible GQs number" (you can decrease the gs_farclipplane_set value to avoid that problem)
  • also, keep in mind that characters are visible only within 4099|4099|4099 and -4099|-4099|-4099 world units
  • geometry stops at ca. X=4228|Z=4228 and -4228|-4228 (height not tested)


Demo files

Demo files can be downloaded here.

First put the new "OniSplit.exe" into the second "lab" folder alongside the xml files.

There's a "build.cmd" file. Those two are the important lines:

onisplit -create:level out lab.xml
onisplit -import:pc out level3_Final.dat

The first line create the *.oni files from a master.xml file, in this case "lab.xml". If final, the oni files can be put into a new AE package.

The second line creates level archives which can be used for fast tests. They don't require you to install a package.

Instead of "nosep" you can now also use "pc" for the import. Mac does still use "sep".

If the game crashes while loading (at ca. 5-10% progress), check if all textures were inside the "out" folder.

You can extract the AKEV file to xml, then search for "TXMP".

"TXMP_marker_door" and "TXMP_marker_ghost" will be missing in the demo's "out" folder.

You can add this between the other two lines in the build.cmd to prevent a crash.

onisplit -create:txmp out env/markers/*.tga


The master xml file

The master xml file name determine the bsl folder name and the AKEV and ONLV file name in the output folder.

trimmed master file "lab.xml" from the demo
mandatory files for level import
  • level_environment.dae
  • level_bnv.dae
  • level_textures.tga/jpg/(dds?)
  • Character.xml with player
<?xml version="1.0" encoding="utf-8" ?>
<Oni>
   <Level SharedPath="../shared">
       <Environment>
           <Model>
               <Import Path="env/lab_env.dae"/>
               <Import Path="env/lab_bomber_window.dae"/>
               <Import Path="env/lab_motorcycle.dae">
                   <Node Id="motorcycle">
                       <ScriptId>9</ScriptId>
                       <GunkFlags>NoCollision</GunkFlags>
                   </Node>
               </Import>
           </Model>
           <Rooms>
               <Import Path="env/lab_bnv.dae"/>
           </Rooms>
           <Textures>
               <Texture Name="GOO">
                   <Format>bgra4444</Format>
                   <GunkFlags>NoCollision</GunkFlags>
                   <Image>env/images/GOO.tga</Image>
               </Texture>
           </Textures>
       </Environment>
       <Sky>sunset</Sky>
       <Objects>
           <Import>Character.xml</Import>
           <Import>Furniture.xml</Import>
           <Import>TriggerVolume.xml</Import>
           <Import>Physics.xml</Import>
       </Objects>
       <Films>
           <Import>films/BomberKonRun01.xml</Import>
           <Import>films/BomberKonRun02.xml</Import>
       </Films>
       <Cameras>
           <Camera Path="cameras/BomberCam01.dae">
               <Animation Name="BomberCam01"/>
           </Camera>
           <Camera Path="cameras/BomberCam02.dae">
               <Animation Name="BomberCam02"/>
           </Camera>
       </Cameras>
   </Level>
</Oni>


Shared folder

The master xml file can link to other xml files, most of them are BINACJBO files. The file type gets declared inside the file, so the file name itself doesn't has to contain the type. Ergo, "BINACJBOCharacter.xml" can be given a simpler name like "Character.xml".

Some resources used by those xml files can be found in a "shared" folder. OniSplit copies textures and "physics" objects into the output folder; furniture objects will be integrate into the AKEV. Unused resources in the shared folder will be ignored. That way the final level archive / AE package contains only necessary files which saves the end-user space.

In the demo are various subfolders in shared folder: consoles, doors, furniture, triggers and turrets. Following file types comes there without their file prefixes: CONS, DOOR, TRIG, OFGA. (Test todo: import files that have those prefixes.)


<Model>

This tag is mandatory (it must be present to avoid errors); the model section contains one import path to the AKEV (level) geometry (*.dae) and can contain additional import paths for exceptions (*.dae).

Data from the demo:

AGQG (Gunk) flags (trimmed list)

see onisplit -help enums for more flags

None
NoCollision
NoObjectCollision
NoCharacterCollision
NoDecal
TwoSided
Invisible
               <Import Path="env/lab_env.dae"/>
               <Import Path="env/lab_motorcycle.dae">
                   <Node Id="motorcycle">
                       <ScriptId>9</ScriptId>
                       <GunkFlags>NoCollision</GunkFlags>
                   </Node>
               </Import>

The motorcycle has here script id 9. You can show and hide the object with bsl command env_show whereby the second parameter means true or false.

env_show 9 1
env_show 9 0


EdT demonstrates here env_show. The objects have collision.


The last original level (syndicate mountain compound) has a big dish platform that can be made hidden. Obviously, such objects/areas can be made to have pathfinding too.


More possible applications of env_show
  • grids in front of ventilation shafts (a little door object could be an alternative)
  • ground/ceiling/objects for cutscenes that become partially destroyed
  • destrucable walls like in Deus Ex 3 (trigger volume, replacing punch anim with punch-through-wall anim)


Breakable objects with BSL recognition

Broken env objects can be recognized by bsl command env_broken (ID_1, ID_N). However, this whole thing requires additional code to work.

An example is the training level. Let's determine how we can set up such a thing.

First we need a trigger volume like in level 1.

       <TRGV Id="11495">
           <Header>
               <Flags>Locked</Flags>
               <Position>-714.6615 -298 -555.2073</Position>
               <Rotation>0 0 0</Rotation>
           </Header>
           <OSD>
               <Name>tv75</Name>
               <Scripts>
                   <Entry></Entry>
                   <Inside>targets_gone</Inside>
                   <Exit></Exit>
               </Scripts>
               <Teams>255</Teams>
               <Size>400 31 270</Size>
               <TriggerVolumeId>75</TriggerVolumeId>
               <ParentId>0</ParentId>
               <Notes></Notes>
               <Flags>PlayerOnly</Flags>
           </OSD>
       </TRGV>

Now we need some BSL code.

var int inside_target_function;

func void enter_target_function(void)
{
   dprint enter_target_function
   inside_target_function = 1;
}

func void exit_target_function(void)
{
   dprint exit_target_function
   inside_target_function = 0;
}

func void targets_are_not_gone(void)
{
	# CB: turn off the trigger volume and sleep for a second
	# so as not to cause hideous performance loss
	trigvolume_enable tv75 0
	sleep 60
	trigvolume_enable tv75 1
}

func void targets_gone(string ai_name)
{
	if(inside_target_function eq 0)
	{	
		enter_target_function() # catch other "targets_gone" functions to let them do nothing

		var int num_broken = env_broken(3001, 3018);
		# if you only one target use scheme: env_broke(3001, 3001)

		if (num_broken eq 18)
		{
			targets_are_gone();
		}
	
		if (num_broken < 18)
		{
			targets_are_not_gone(); # to set check interval to one second
		}

		exit_target_function
	}
}

func targets_are_not_gone
{
	trigvolume_enable tv75 0
	# [...]
}
Explanation

Player enters the TV, "targets_gone" gets triggered. The variable "inside_target_function" should be 0 be default, so we are entering now the first if statement. Next, we can assume that the player didn't destroy all glass objects, so "num_broken" will be less than 18: "targets_are_not_gone" gets triggered.

The TV function "targets_gone" would be triggered every frame but "targets_are_not_gone" decrease the check interval: The TV gets deactivated for 60 frames. Then the TV becomes enabled again and will start anew until all glass objects got destroyed or Player left the TV.

Unnecessary "targets_gone" functions will do nothing because "inside_target_function" was set to 1 by the first one.

"targets_are_not_gone" eventually disables the TV to prevent memory overflow, the function contains also all things "[...]" that you want to happen after the glass target broke.


Texture exchange

BSL command supported for PC and Mac:

env_texswap ID texture

Might be useful to switch on/off static and animated textures. (News screen: running or off or smashed. Lava stream: flowing or stagnating or cooled down. Etc.)


<Rooms>

This tag is mandatory. It contains a link to BNV data (*.dae) which is used to create pathfinding grids.


<Textures>

This tag is mandatory. Textures become imported as they are; in the texture section you declare exceptions.

format flags
BGR
RGBA
BGR555
BGRA5551
BGRA4444
AGQG (Gunk) flags (trimmed list)

see onisplit -help enums for more flags

None
NoCollision
NoObjectCollision
NoCharacterCollision
NoDecal
TwoSided
Invisible

making_a_surface_transparent_and_twosided_tn_zpsfa00879e.png

               <Texture Name="GOO">
                   <Format>bgra4444</Format>
                   <GunkFlags>NoCollision</GunkFlags>
                   <Image>env/images/GOO.tga</Image>
               </Texture>
  • There you can give a texture a special format, for example "bgra4444", to make it transparent.
  • Use gunkflag "TwoSided" to make surfaces visible from both sides.
  • If the texture comes with gunkflag "NoCollision" then all objects with that texture will have no collision. Characters would fall through it.

Both makes sense, let's say, for a water-like substance. The biolab use this for an area with green acid.


TwoSided objects

It's also possible to set this in Mod Tool. Use one image source for diffuse and transparency.

It won't work with two images sources even if both sources use the same image. See screenshot if you are still unsure about this.


<Objects>

Character.xml

This file is mandatory. It has to contain a player character or else Oni crashes when ca. 60% of the level got loaded.


Furniture.xml

The AKEV core geometry is more or less unique while this furniture file adds standard objects to it.

Between the <Class> </Class> tags is always a link to an OFGA file.

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <Objects>
       <Furniture>
           <Header>
               <Flags>Gunk</Flags>
               <Position>-62.692 -29 108.35</Position>
               <Rotation>181.522 356.021 178.114</Rotation>
           </Header>
           <OSD>
               <Class>furniture/V_tctf_bigvan.oni</Class>
           </OSD>
       </Furniture>
   </Objects>
</Oni>


Physics.xml

This file is for objects with "physics". Unlike AKEV core geometry or furniture, those objects can be animated.

For documentation purpose the file here has been trimmed down.

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <Physics>
object setup flags
None
InUse
NoCollision
NoGravity
FaceCollision
object animation flags
None
NormalLoop
BackToBackLoop
RandomStartFrame
Autostart
ZAxisUp
       <Object Name="motorcycle">
           <ScriptId>8</ScriptId>
           <Flags>FaceCollision</Flags>
           <Import Url="motorcycle/export.dae">
               <Animation Name="motorcycle02">
                   <Flags>AutoStart</Flags>
                   <End>880</End>
               </Animation>
               <Animation Name="motorcycle02_stop">
                   <Start>881</Start>
               </Animation>
           </Import>
       </Object>
   </Physics>
</Oni>

In this example OniSplit takes the "export.dae" file, looks what parts it contains and creates geometry files from it.

  • M3GMhubs_rear.oni
  • M3GMhubs.oni
  • M3GMmotocycle.oni

It's a nice feature that hierarchies are supported here.

The motorcycle is made of 3 parts so 3 object animations (OBAN) will be created up to frame 880. Then OniSplit creates 3 more OBANs starting from frame 881.

The reason for the interruption at frame 880 is probably to give barabas a few more frames of glory in the cutscene.

  • OBANmotorcycle0200.oni
  • OBANmotorcycle0201.oni
  • OBANmotorcycle0202.oni
  • OBANmotorcycle02_stop00.oni
  • OBANmotorcycle02_stop01.oni
  • OBANmotorcycle02_stop02.oni


Notes about BSL usage

The bio lab script file use the motorcycle objects and animations like this:

	env_show 9 0		# hide solid motorcycle parts (because they get visible at level start)
	# in the original game the motorcycle is separated in object 8, 9 and 10
	# also the OBAN files have a bit different names

	# obj and env objects are totally independent from each other
	# so their script ids might not be the same

	obj_create 8 10		# create animation-ready non-collision motorcycle parts
	env_anim 8 10		# animate those parts (not necessary if OBAN flag is "AutoStart")

	# the first animations would loop because of "AutoStart"
	# so get the right timing to apply the other animations
	# "motorcycle02_stop00" and the others will not loop because they don't have "AutoStart"
	env_setanim 8 motorcycle02_stop00 # motorcycle
	env_setanim 9 motorcycle02_stop01 # hubs
	env_setanim 10 motorcycle02_stop02 # hubs_rear

	obj_kill 8 10		# delete animated parts
	env_show 9 0		# show solid motorcycle parts


Exported Oni Level (ONLV*.xml)

skybox file ONSKafternoon
ONSKafternoon_tn.png

File structure

  • ONLV instance
<Name> - this is your BSL folder (save game slot and level number are defined inside ONLD)
<Environment> - link to AKEV file (solid level geometry)
<Objects> - link to OBOA instance (animated level geometry, sometimes particles)
<SkyBox> - link to ONSK file, originally there are 4 files in level 0: crapsky, night, sunset, afternoon
<Characters> - link to AISA file (pendant of BINACJBOCharacter file), holds character spawn collection
<ObjectQuadMap> - link to ONOA instance (maybe spawnable / function holding objects ?)
<Particles> - link to ENVP instance (pendant of BINACJBOParticle), holds particle spawn collection, door lock lights are typically stored inside ENVP
<Corpses> - link to CRSA instance (corpses consist of 19 body parts)
  • OBOA instance
...
  • ONOA instance
...
  • ENVP instance
...
  • CRSA instance
...
  • M3GA
...
  • IDXA
...


Flags in the <OBOAObject> section

These are also used for the physics.xml file

<Flags>
InUse
NoCollision
NoGravity
FaceCollision
<PhysicsType>
None
Static
Linear
Animated
Newton


Sample code from a trimmed warehouse level.

[...] mean another Corpse code block. There are usually 20 in total. They are somehow needed to prevent bugs.

<?xml version="1.0" encoding="utf-8"?>
<Oni>
   <ONLV id="0">
       <Name>EnvWarehouse</Name>
       <Environment>AKEVEnvWarehouse</Environment>
       <Objects>#1</Objects>
       <SkyBox>ONSKafternoon</SkyBox>
       <Characters>AISAlevel1_scripts</Characters>
       <ObjectQuadMap>#2</ObjectQuadMap>
       <Particles>#3</Particles>
       <Corpses>#4</Corpses>
   </ONLV>
   <OBOA id="1">
       <Objects />
   </OBOA>
   <ONOA id="2">
       <Elements />
   </ONOA>
   <ENVP id="3">
       <Particles />
   </ENVP>
   <CRSA id="4">
       <FixedCount>0</FixedCount>
       <UsedCount>0</UsedCount>
       <Corpses>
           <CRSACorpse>
               <CharacterClass></CharacterClass>
               <Transforms>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
                   <Matrix4x3>0 0 0 0 0 0 0 0 0 0 0 0</Matrix4x3>
               </Transforms>
               <BoundingBox>
                   <Min>0 0 0</Min>
                   <Max>0 0 0</Max>
               </BoundingBox>
           </CRSACorpse>
          [...]
       </Corpses>
   </CRSA>
</Oni>

not empty OBOA - example from level 19

(exported ONLV files seem to contain 32 empty <OBOAObject> sections)

If I remember correctly this one is only an object for the cutscene. Maybe the real floor(s) (those with collision) can be tracked down with the id used by bsl.


           <OBOAObject>
               <Geometry>#347</Geometry>
               <Animation>OBANDishFloor01</Animation>
               <Particle></Particle>
               <Flags>InUse</Flags>
               <DoorGunkId>0</DoorGunkId>
               <DoorId>0</DoorId>
               <PhysicsType>Animated</PhysicsType>
               <ScriptId>204</ScriptId>
               <Position>-183 99.59154 -2501.25</Position>
               <Rotation>0.7071067 -1.545431E-08 1.545431E-08 0.7071068</Rotation>
               <Scale>1</Scale>
               <Transform>1 -4.371139E-08 -5.21253064E-16 0 1.19248806E-08 -1 4.371139E-08 1 1.19248806E-08 -183 99.5815353 -2501.25</Transform>
               <Name>object_DishFloor01</Name>
           </OBOAObject>


not empty ENVP - example from level 19

           <ENVPParticle>
               <Class>locklight</Class>
               <Tag>mainchamber_locklight01</Tag>
               <Transform>1 -4.559326E-08 1.35404189E-05 -1.354042E-05 -2.03512554E-05 1 -4.53176945E-08 -1 -2.03512554E-05 -391.790527 58.0480423 -1364.412</Transform>
               <DecalScale>1 1</DecalScale>
               <Flags></Flags>
           </ENVPParticle>

<Transform> - the last 3 values are the position (x, y, z)

<Flags>

NotInitiallyCreated


Exported Akira Environment (AKEV*.xml)

Somehow I would like to have the AKEV and ONLV information on one page (like the sound stuff on SNDD). Let's see how this turns out.


AGQG flags - appears to be used by textures.xml <GunkFlags> (just some or all of them ?)

DoorFrame (invisible quad that uses the TXMP_DOOR_FRAME texture)
Ghost (pathfinding volume separator, see AKVA etc)
StairsUp
StairsDown
Stairs
Triangle
Transparent
TwoSided
NoCollision
Invisible
NoObjectCollision
NoCharacterCollision
NoOcclusion
Danger
Horizontal (slope > 70°)
Vertical (slope < 70°)
GridIgnore
NoDecals
Furniture
ProjectionBit0
ProjectionBit1
SoundTransparent
Impassable


(Copied from hex page. Is this still up to date ?)

Triangles
Many quads are in fact triangles: the last two vertices have the same PNTA and TXCA entries, and the ARGB color is (255, 205, 205, 205) (80% gray, 100% opaque). There is also a flag specifying that.
Ghost, StairsUp, StairsDown
These flags are used for BNV adjacencies, see AKAA. Stairs up/down are used instead of Ghost when the quad is placed at the bottom/top of the stairs. These quads are not visibile. The script variable env_show_ghostgqs is intended to control the visibility of such quads but it requires "debug" level files.
There are a couple of ghost quads that aren't referenced from AKAA. It's likely that those quads are useless.
DoorFrame
This appears to be another type of "ghost" quad (its visibility is controlled by the same env_show_ghostgqs variable). Sometimes it is used together with the Ghost flag but not always. Only the door frames that also have the Ghost flag are used as adjacencies so it's unclear if the rest of the door frames serve any purpose. In fact it appears that this flag has no effect other than making the quad invisible.
Stairs
This is applied to the invisible ramp quad that covers the stairs. In general this flag is also applied to the visible stairs geometry but there are some exceptions (errors? see level 19 stairs).
NoOcclusion
This flag tells the octtree raycaster to ignore the quad when doing ray/quad intersections. This is tipically used for small quads that are unlikely to affect the overall environment visibility.
ProjectionBit
These 2 flags can be 00, 01, 10 and 11. That means the values 0,1,2 and 3 which have the following meanings:
  • 0 - No projection plane specified. One can be computed if needed. Never used in files, may slow down the game if used.
  • 1 - Project quad on XY plane.
  • 2 - Project quad on XZ plane.
  • 3 - Project quad on YZ plane.
The projection plane is used to determine if a point is in a quad (this point is usually the result of an intersection between a ray and the quad plane).
GridIgnore
Appears to be unused. Its likely purpose is to mark quads that don't count as obstacles in the pathfinding grid.
Danger
Appears to be unused. Its likely purpose is to create danger areas in the pathfinding grids. Usually there's a trigger volume nearby that hurts/kills the character. This quads are always invisible.
Invisible
Invisible quads have a couple of different uses:
  • block player access to some parts of the environment
  • stairs ramp
  • collision geometry (used by some "complex" furniture)
  • danger quads (see above)
  • some other apparently useless quads
Furniture
Set for all quads that belong to a furniture object. It doesn't appear to be used. It is also redundant since all the furniture quads have an object id.
NoDecals
Prevents the creation of decals on the quad. Set for door quads because the decals would disappear when the door opens. That's why shooting a door doesn't leave a mark.
Impassable
Probably used by forcefields and end of level boundaries (like in state archive level).


Ideas to test out

None ATM.


Ideas that has been tested

Sky dome - it's a fail

sky box
ugly_skybox_lines_tn.jpg
sky dome
sky_dome_512x512_tn.jpg

Maybe it's possible to create a very big sphere or dome that covers the entire level (and let Oni's skybox unused). If it's doable it could avoid ugly lines of the skybox coming from OpenGL rendering.


Update: 12 June 2012

New issues appeared that need to take care about:

  • brightness:
The brightness can be somewhat influenced by BSL commands like with gl_fog_..., gs_farclipplane and must be set adequately.
  • texture size:
The dome seen in the screenshot has a texture size of 512x512 and hence looks quite pixelated.
The problem might be solved by splitting the dome into sectors and giving each sector its own texture.


gl_fog_start=.99999
sky4sectors_b_tn.jpg
test level over HERE
sky4sectors_a_tn.jpg

Update: 14 June 2012

  • texture boarder and distortions:
Texture boarders have darker pixels so the UV must not reach them. Also after splitting the textures inside the editor there will be little distortions but they are still noticeable enough to make the sky look odd. Fine-tuning the UVs didn't really help.
  • The gs_farclipplane max value makes the size of the dome quite limited: I think that the max radius here is somewhere between 2500 and 5000 world units.

I consider this as a fail. Oni would need bigger view range and a texture support of 2096x2096.


Ideas for onisplit

Neo might update OniSplit so that it is searching specific strings in object names of a dae level file.


Cutscene cams

  • string "cutsceneN" (e.g. cutscene231) -> OBAN


Doors

  • string "door*" (e.g. doorBlastDoorMX2000) -> DOOR + BINACJBODoor + OBAN
    • but if the string is "door*cloneN" then the DOOR and OBAN creation gets skipped (e.g. doorBlastDoorMX2000clone3), only class name, rotation and position get written into BINACJBODoor


Animated objects

  • string "*_BeforeAnim": that's first static object with collision data (e.g. BlueCar1_BeforeAnim)
  • string "*_InAnim": that's the animated cutscene object (e.g. BlueCar1_InAnim)
  • string "*_AfterAnim": that's the second static object with collision data (e.g BlueCar1_AfterAnim)


Fake-destructible objects

  • string "*_BeforeAnim": that's first static object with collision data (e.g. ConcreteWall2_BeforeAnim)
  • string "*_FragmentN": that's the group of animated cutscene objects (fragments of the static object) (e.g. ConcreteWall2_Frag5)
  • string "*_ColFragN": that's the group of static objects with collision data (e.g. ConcreteWall2_ColFrag5)
  • string "*_NoColFragN": that's the group of static objects without character collision (e.g. ConcreteWall2_NoColFrag5)
    NoColFrag would be useful if the fragments are quite numerous and small and hence would pose a problem to the pathfinding