XML:ONLV
ONLV : Oni Game Level | ||
---|---|---|
XML
ONLD << Other file types >> ONSK |
This page is unfinished. Can you fill in any missing information? |
- Todo list
- tips with cutscene charas: sync pelvis OBAN and partner TRAM
- notes on camera and film import ?
Level releases, forum threads and wiki pages
- Custom levels that have been created so far
- Island Level (7/9/13) uses level 29
- City Level Part 1 (12/7/13) uses level 23
- Fight Club (1/6/13) uses level 25
- Old China (12/5/12) uses level 24
- Boss Battle (18/3/12) uses level 23
- Parkour Challenge 2 (23/1/12) uses level 21
- Parkour Challenge (16/1/12) uses level 21
- Mini-Partenon (25/7/11)uses level 5
- Hexagon (3/7/11)level 16
- Junkyard (23/6/11) uses level 15
- Arena (8/11/10) uses level 7
- Maze (15/2/10) uses level 5
- Muro's Lair - Preview (3/10/11) uses level 20
- OCF threads about level creation
- "Creating the Lair - A level tutorial"
- "Creating new levels"
- "Create levels with pathfinding grids"
- "More questions about levels"
- "Sketchup tutorials for making levels"
- "Modding Existing levels - Beta" ("Moveable furniture" post)
- Wiki pages about levels
- Free texture resources
- various game meshes
- various game textures
- various game textures
- skies and objects of the solar system
- skies
- skies
Concept phase
Be aware of limitation of level and engine.
- triangle limit of a game level: ca. 520.000 (500.000 to be on save side)
- (formerly "XSI") Mod Tool can save dae files with max. 64.000 triangles per object
- when polygons are too tightly packed the cam will look at too many of them and glitches appear: the visible GQs (GunkQuads) limit is 8192 (2^13), higher numbers will cause render bugs and call BSL message "Exceeded max visible GQs number"; limited solutions to this:
- decrease the gs_farclipplane_set value
- hide objects by env_show
- hide objects by level design
- for example departments in a building could be quite detailed because the view at the other departments/rooms is blocked by non-transparent walls
- The camera can look at 2049 transparent textures at once, one more and Oni crashes.
- 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)
- chr_debug_spheres = 1 visualizes collision spheres of characters, then you can check if they fit through a new entrance
Notes on Mod Tool and Google Sketchup
Re-saving a dae file - that was originally made in Sketchup - in Mod Tool can result in a surprising change in size within Oni.
That due to a difference in the length specification.
- For example Sketchup dae file has: <unit meter="0.0254000" name="inch" />
- Re-saved Mod Tool dae file has: <unit meter="0.1" name="decimetre"></unit>
In that case you would need to open the new dae inside a text editor and change the length specification again.
Level import with OniSplit v0.9.82.0+
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.exe -create:level out lab.xml OniSplit.exe -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. 90% progress), be sure that the texture's x and y (pixel) dimension are power of two: 512, 256, 128, 64, etc.
If the game crashes while loading (at ca. 50-60% progress), be sure that the BINACJBOCharacters/AISA file has a player character.
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 the TXMP array.
- THIS script checks which textures are missing by comparing the AKEV*.xml with its *.oni files folder. Adapt the two paths so that it works for you. Alt + 4, insert code, then F5.
"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.exe -create:txmp out env/markers/*.tga
The master xml file
File paths can be either absolute or relative.
The master xml file name determine the bsl folder name and the AKEV and ONLV file name in the output folder.
Mandatory files for level import:
- level_environment.dae
- level_bnv.dae
- level_textures.tga/jpg/png
- Character.xml or AISA with player
- ONSK name in <Sky> (can be fake name)
- ONLD file (for new levels; read on HERE about savegame unlocking)
XML tag | content type | description |
---|---|---|
<?xml version="1.0" encoding="utf-8"?> | float, flag | Ignore this. |
<Oni> | - | |
<Level SharedPath="..."> | link | 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 have 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. OniSplit recognize them nonetheless. |
<Environment> | - | |
<Model> | - | Used to import level geometry and static objects. See HERE for detailed information. |
<Import Path="..."/> | link | |
<Node Id="..."> | string | informative (space for notes so to say) |
<ScriptId> | integer | Tested with BSL command ...
Static objects store their Id in one of AKEV's IDXA instances. |
<GunkFlags> | flag |
see OniSplit -help enums for more flags
|
<Rooms> | - | For detailed information see HERE.
For Google Sketchup BNV tutorial see HERE. |
<Import Path="..."/> | link | File path to *.dae file. BNV data, used to create pathfinding. |
<Textures> | - | With OniSplit v0.9.94.0+ you can use attributes to set the default import formats and max dimensions. For example:
Textures that aren't power of two (2^x) or bigger than 512 will be scaled to be that way. For example: 2003x2000 becomes 512x512. |
<Texture Name="..."> | string | TXMP file name to generate. |
<Flags> | flag | Optional tag. For list of flags see HERE. |
<Format> | flag |
|
<GunkFlags> | flag |
see OniSplit -help enums for more flags
|
<Image> | link | File path to *.tga/jpg file. |
<Sky> | string | ONSKfile.oni (without file pre- and suffix)
The import doesn't work with an empty tag. <Sky>clear</Sky> helps here; any other fictional name will also do. For detailed information see HERE. |
<Objects> | - | |
<Import> | link | File path. Supported files:
|
<Films> | - | |
<Import> | link | File path to *.xml file. OniSplit creates a FILM file from it. Used for characters in cutscenes. |
<Cameras> | - | |
<Camera Path="..."> | link | File path to *.dae file. OniSplit creates an OBAN file from it. Used for cutscenes. |
<Animation Name="..."/> | string | Name for the OBAN file. |
This is a trimmed version of the master file "lab.xml" from the demo. It's meant to give you a first impression. -- We might upload a smaller demo someday with all features nonetheless.
<?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>
<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:
<Import Path="env/lab_env.dae"/> <Import Path="env/lab_motorcycle.dae"> <Node Id="motorcycle"> <ScriptId>9</ScriptId> <GunkFlags>NoCollision</GunkFlags> </Node> </Import>
env_show
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. Never use 0 as id because it won't work.
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 satellite dish platform that can be made hidden. Obviously, such objects/areas can be made to have pathfinding too.
- More possible applications of env_show
- 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)
- grids in front of ventilation shafts (a little door object could be an alternative)
- at the moment this can't be done because characters can't sneak under the top edge of the opening (the characters collision spheres are too big)
- managing object groups with trigger volumes (save multiple objects in one dae file)
Breakable glass 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_gone { trigvolume_enable tv75 0 # [...] }
- Explanation
Player enters the TV, "targets_gone" gets