WebFun
In 1996/97 LucasArts released two games forming the Desktop Adventures series – Indiana Jones and His Desktop Adventures and Yoda Stories. Both games are 2D puzzle games, featuring a top-down view, a variety of quests and randomly generated worlds.
WebFun aims to be a faithful re-implementation of the game engine driving the Desktop Adventures series and document to its inner workings.
This documentation describes various observations made while reverse-engineering the games. Some of it applies to Indiana Jones and His Desktop Adventures as well, but due to personal preference most of the reverse-engineering efforts have been focused on Yoda Stories.
Releated Projects
The Desktop Adventures games have infected quite a few people over the years. Here are some projects with similar goals as WebFun.
Project | Language | Description |
---|---|---|
LeonisX/yoda-stories-translation-tool | Java | Yoda Stories Translation Tool |
LeonisX/YExplorer | Delphi | Yoda Stories DAT file explorer, superseded by yoda-stories-translation-tool |
shinyquagsire23/DesktopAdventures | C | Reimplementation |
IceReaper/DesktopAdventuresToolkit | Java | packer / unpacker for game files |
digitall/scummvm-deskadv | C++ | reimplementation for use in ScummVM |
Project Architecture
This section describes some of the fundamental structures underlying WebFun.
Getting Started
To set up a local development environment you'll need:
- Git to download the source code
- Node.js, version 14 or newer
- Yarn to install dependencies and run dev tasks
Get the Source Code
Open your terminal and execute the following script to download the repository:
git clone https://github.com/cyco/webfun
Install dependencies
To download and install all dependencies change into the new directory created by git clone
and run yarn
:
cd webfun
yarn install
Start the server
Using yarn
again from the project directory you can now start a local web server. Run the following command in your terminal and the local page will be opened in your default browser.
yarn start
Now you're all set up. The development page will reload whenever a code change is detected. See Build System for a list of tasks yarn
can execute for you.
When you're done hit CTRL
and c
on your keyboard to stop the server.
Data Sources
By default WebFun is set up to load game assets from archive.org. For local development it's often helpful to load the files from disk and speed things up a bit. WebFun uses an environment variable called WEBFUN_GAMES
to determine where to find games.
To override the default configuration (stored in the file .env.defaults
), you can either set it in your shell before starting the web server or create a new file .env
and put the value there. The value of the variable should be a JSON
encoded array of GameSource objects.
Note: Environment variables are only read when a program is started. Make sure to restart your development server after making changes to
.env
The following configuration adds a local Yoda Stories installation to the default archive.org game source.
WEBFUN_GAMES=[{"title":"Yoda Stories (local)","variant":"yoda","data":"game-data/YODESK.DTA","exe":"game-data/YODESK.EXE","help":"game-data/YODESK.HLP","sfx":"game-data/SFX/"},{"title":"Yoda Stories from archive.org","variant":"yoda","exe":"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2FYodesk.exe","sfx":"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2Fsfx%2F","data":"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2Fyodesk.dta","help":"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2FYodesk.hlp"}]
Build System
WebFun uses the package manager yarn to manage dependencies and run build scripts.
The following tasks are defined in package.json
and can be started using yarn <task-name>
on the command line.
start -- Start a local web server for development.
By default this starts the server on localhost
port 8080
. You can change the hostname to listen on with the environment variable host
. Some features like the service worker might require an HTTPS connection to work properly. If you place a self-signed certificate under config/ssl.key
and config/ssl.pem
the server will accept HTTPS connections.
Assuming you have mapped webfun.local
to 127.0.0.1
in your hosts file (like echo "127.0.0.1 webfun.local" >> /etc/hosts
), you can use mkcert to generate certificates that will be valid on your system like this:
# change to the project directory
$ cd webfun
# create a certificate
$ mkcert -cert-file config/ssl.pem -key-file config/ssl.key webfun.local localhost 127.0.0.1 ::1
# start the development server with the proper hostname
$ host=webfun.local yarn start
format -- Format source code files using eslint & prettier. You should always run this task before committing a code change to make sure everything is properly formatted and adheres es to the coding standards.
test -- Run basic test suite once without collecting code coverage.
test:cont -- Run unit test whenever a change is detected. This task does not collect collect code coverage for performance reasons.
test:full -- Run all tests and collect code coverage.
test:unit -- Run unit tests with code coverage enabled.
test:unit:cont -- Run unit tests with code coverage whenever a change is detected
build -- Clear build
directory and run a fresh build suitable for production.
build:docs -- Build this documentation. This script requires mdbook
to be installed, see documentation for details.
Webpack
Webpack is used to bundle scripts and prepare other assets like css stylesheets, fonts and copy static files in production builds. The following configuration files are used for various tasks, all of them are located in the config
directory:
webpack.commmon.js -- A shared configuration that is used as a base for the dev and test configurations.
webpack.dev.js -- Configuration for the development task, the development web server with hot module reloading is defined here.
webpack.test.js -- Used for running tests
webpack.prod.js -- Defines the production build
webpack.service-worker.js -- Defines the production build for the service worker script. This is in a separate file because splitting the service worker code via chunks does not produce a file that runs in the service worker context.
Custom Plugins
WebFun uses a few custom webpack plugins. These are all single-file scripts found in the config
directory.
file-list-webpack-plugin -- Creates a list of files produce during a production build and stores it in a json file. This file is used to pre-load assets when the service worker is installed.
spy-on-imports-webpack-plugin -- This plugin rewrites imports created by Webpack so jasmine.spy
can be used on wildcard module imports to mock dependencies during test execution:
import * as UtilModule from "src/util";
describe("some test", () => {
beforeEach(() => spyOn(UtilModule, "download"));
it("starts a download", () => {
subject.doYourThing();
expect(UtilModule.download).toHaveBeenCalled();
});
});
Documentation
This source for documentation is at docs
and built using mdbook. You can trigger a manual build by executing the following command from the project root:
$ yarn build:docs
The resulting files are placed in build/docs/
.
Mdbook also supports starting a local web server to render a live preview of changes made to the markdown files:
$ cd docs
$ mdbook serve
Plugins
Currently there are two plugins used during compilation of the documentation. You'll probably have to install them manually.
mdbook-linkcheck is included to check that all links the documentation points to are valid.
mdbook-open-on-gh adds a link to the current page on GitHub at the bottom of each page.
You can install the plugins with cargo from you command line:
$ cargo install mdbook-linkcheck mdbook-open-on-gh
Deployment
WebFun is hosted on GitHub pages using the branch release
with a custom domain. The deployment process takes several steps, automated by this simple shell script:
#!/usr/bin/env bash
SOURCE="$HOME/Source/webfun"
TARGET="$HOME/Source/webfun-release"
# Stop on errors
set -e
# Clone release branch to $TARGET if it does not exist
if [ ! -d "$TARGET" ]; then
git clone -b release git@github.com:cyco/WebFun.git "$TARGET"
fi
# Change to project root
cd "$SOURCE"
# Execute full test suite
yarn test:full
# Set environment variable to load game files from archive.org
export WEBFUN_GAMES="[{\"title\":\"Yoda Stories from archive.org\",\"variant\":\"yoda\",\"sfx-format\":\"wav\",\"exe\":\"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2FYodesk.exe\",\"sfx\":\"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2Fsfx%2F\",\"data\":\"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2Fyodesk.dta\",\"help\":\"https://cors.archive.org/download/Star_Wars_-_Yoda_Stories_1997_LucasArts/Star%20Wars%20-%20Yoda%20Stories%20%281997%29%28LucasArts%29.iso/Yoda%2FYodesk.hlp\"},{\"title\":\"Yoda Stories Demo (archive.org)\",\"variant\":\"yoda-demo\",\"sfx-format\":\"wav\",\"exe\":\"https://cors.archive.org/download/StarWarsYodaStories_1020/YodaDemo.zip/YodaDemo%2FYodaDemo.exe\",\"sfx\":\"https://archive.org/download/StarWarsYodaStories_1020/YodaDemo.zip/YodaDemo%2Fsfx%2F\",\"data\":\"https://cors.archive.org/download/StarWarsYodaStories_1020/YodaDemo.zip/YodaDemo%2FYodaDemo.dta\",\"help\":\"https://cors.archive.org/download/StarWarsYodaStories_1020/YodaDemo.zip/YodaDemo%2FYodaDemo.hlp\"}]"
# Run production build
yarn build
# Run production build of documentation
yarn build:docs
# Build docker container for local deployment
# docker build -t webfun:latest .
# Clear out target directory
rm -r "$TARGET"/*
# Copy release files
cp -r build/* "$TARGET"
# Copy screenshots for landing page
cp -r docs/screenshots "$TARGET"/docs/screenshots
cp -r assets/preview.png "$TARGET"/preview.png
# Re-create CNAME to setup custom URL for GitHub pages
echo -n www.webfun.io > "$TARGET"/CNAME
# Change directory for manual inspection
cd "$TARGET"
# Stage new version
git add .
# Give further instructions
echo ""
echo "Your relase is ready. Please inspect changes manually and the run"
echo ""
echo " cd \"$TARGET\""
echo " git commit -m \"chore: Update release\""
echo " git push"
echo ""
Gameplay
The following section describes various aspects of the gameplay.
Window
Desktop Adventures are played in a window. There's no fullscreen mode and no resolution choices. The virtual world is rendered in a 288
x288
pixel view. The player's item are dispalyed in an inventory table to the right. Each item can be clicked to pick up and then dropped on the scene. Below the inventory you'll find a compass that shows where the player can go, and indcator for the currently equipped weapon plus remaining ammo and a circular health indicator. As the hero takes damage this changes from green, over yellow and red to black. Once the black circle is completed the player dies and the game is over.
Color Palette
Color cycling effects in Yoda Stories |
Like many older games, the Desktop Adventures engine uses a color palette for rendering. That means the colors you see on the screen are not specified directly by supplying values for the three components red, green and blue, but rather by choosing one of several pre-defined colors from a color palette.
This has two major advantages. First, the amount of data needed to store an image is drastically reduced. Instead of giving three values for each pixel of an image, only one value is enough.
Second, and more interesting nowadays, changing a color in the palette affects all pixels on screen. This allows for very efficient animations and the results for cleverly composed images can be pretty impressive. Check out this site as well as Mark Ferrari's excellent talk 8 Bit & '8 Bitish' Graphics-Outside the Box to see what can be done with palette animations.
Layout of the color palette in a hex editor |
The Desktop Adventures engine uses a palette composed of 256 24
-bit BGR colors, each represented as a 32
-bit integer, totaling 1024
bytes. By convention, the color at index 0
is interpreted as transparent.
Here are the color palettes used by Yoda Stories and Indiana Jones and His Desktop Adventures:
Indy's Desktop Adventures | Yoda Stories |
---|---|
As described in the links above, the Desktop Adventures engine allows for color cycling animations to make the static environments more lively. Each game has a hard-coded set of regions in the palette that shifted to make animations. Each run is either advanced every frame (fast animations) or every other frame (slower animations).
Consult the following tables for a description of the animated regions in each game:
Color Cycles in Yoda Stories
Start | End | Length | Speed |
---|---|---|---|
0A | 0F | 6 | fast |
C6 | C6 | 2 | slow |
C8 | C9 | 2 | slow |
CA | CB | 2 | fast |
CC | CD | 2 | fast |
CE | CF | 2 | fast |
D7 | DF | 9 | slow |
E0 | E4 | 5 | fast |
E5 | ED | 9 | slow |
EE | F3 | 6 | fast |
F4 | F5 | 2 | slow |
Color Cycles in Indy's Desktop Adventures
Start | End | Length | Speed |
---|---|---|---|
A0 | A7 | 8 | fast |
E0 | E4 | 5 | fast |
E5 | ED | 9 | fast |
EE | F3 | 6 | slow |
F4 | F5 | 2 | slow |
Here are some renderings of the animations in the color palette:
Indy's Desktop Adventures | Yoda Stories |
---|---|
Extracting the color palette
The color palette is contained in the .data
section of the game's executable Yodesk.exe
as well as the demo YodaDemo.exe
. Since the exact offset might differ depending on the specific version or language of the game, the easiest way to find it is to locate the string CDeskcppDoc\0
and extract the next 1024 bytes from there. In most versions the palette seems to start at offset 0x550F0
.
For Indy's Desktop Adventures a reliable way to extract the color palette is to search for the ASCII string sss
, move back 103
bytes and read 0x400
bytes from there.
"Free" colors
The following colors are not referenced by any tile in Yoda Stories and could be used for UI elements in restricted environments (e.g. ScummVM or gaming console).
3, 4, 5, 6, 7, 8, 196, 197, 198, 199, 206, 246, 247, 248, 249, 250, 251, 252, 253, 254
Tiles
The Desktop Adventures engine is almost entirely tile based. That means small re-usable images are used as the fundamental elements for all graphics. Maps, enemies and bullets are all made up of tiles.
Note: Only the startup image and the speech bubbles are not rendered using tiles.
Each tile is made up of 32x32
pixels image data – an array of 8
-bit color palette indexes – and some flags that specify the properties of the tile.
General Attributes
bit | Name | Description |
---|---|---|
0 | Transparent | if set color 0 in pixel data is treated as transparent |
1 | Floor | Tile is usually placed on the lowest layer of a zone |
2 | Object | Tile is normally placed on the middle |
3 | Draggable | If set the tile can be dragged and pushed |
4 | Roof | Object is usually placed on the top layer |
Type | ||
5 | Locator | Tiles used in map screen |
6 | Weapon | Weapon tiles |
7 | Item | Items |
8 | Character | If the flag is not set, an enemy can |
Floor
bit | Name | Description |
---|---|---|
16 | Doorway | These tile are doorways, monsters can't go |
Locator
If the Locator
type bit is set, these flags specify the sub-type. Some tiles required to render the map scene are not marked with special bit flags, so a hard coded list of tile ids per game is required.
bit | Name | Description |
---|---|---|
17 | Town | Marks the Spaceport or Lucasino |
18 | PuzzleUnsolved | A visited sector with a puzzle that has not been solved yet |
19 | PuzzleSolved | A solved sector |
20 | TravelUnsolved | Sector that brings to player to a section of the world that can not be reached otherwise. |
21 | TravelSolved | |
22 | BloackadeNorthUnsolved | A puzzle that has to be solved before the sectors to the north can be reached. A sector that has to be solved before the sector to the north can be reached. |
23 | BloackadeSouthUnsolved | |
24 | BloackadeWestUnsolved | |
25 | BloackadeEastUnsolved | |
26 | BloackadeNorthSolved | |
27 | BloackadeSouthSolved | |
28 | BloackadeWestSolved | |
29 | BloackadeEastSolved | |
30 | GoalUnsolved | The final puzzle of the world. Solving this wins the game |
31 | YouAreHere | Overlay to mark the current position |
Item
These item flags are used in hints in the map screen, and in R2D2's help messages.
bit | Name | Description |
---|---|---|
16 | Keycard | |
17 | Tool | |
18 | Part | |
19 | Valuable | |
20 | Map | |
22 | Edible | Medikits and other health items have this flag, their health bonus is hard coded in Yoda Stories |
Weapon
bit | Name | Description |
---|---|---|
16 | BlasterLow | Blaster Pistol |
17 | BlasterHigh | Blaster Rifle |
18 | Lightsaber | Lightsaber (Blue or Green) |
19 | TheForce | The Force |
Character
bit | Name | Description |
---|---|---|
16 | Hero | |
17 | Enemy | |
18 | NPC |
Zones
Zones are the game's maps, where the hero can walk around, solve puzzles and fight monsters.
They are made up of 9x9
or 18x18
tiles in three layers. A ground layer, and object layer, used for collision detection, and a roof layer that is rendered above the hero.
Each zone has a type that is used in the world generation process. See the following table for a list of zone types:
Type | Name | Description |
---|---|---|
0 | None | |
1 | Empty | An empty zone |
2 | Blockade North | Blocks access to zones north of this one until solved |
3 | Blockade South | Blocks access to zones south of this one until solved |
4 | Blockade East | Blocks access to zones east of this one until solved |
5 | Blockade West | Blocks access to zones west of this one until solved |
6 | Travel Departure | When solved this allows the player to reach a zone on an island that can otherwise not be reached by moving between zone on the main world |
7 | Travel Destination | Counterpart to Travel Departure . This is where a here will land after traveling from the departure zone. The zones are connected via hotspots of type TravelStart and TravelEnd |
8 | Room | Rooms can n not be placed directly on the main world. They can be only be reached through DoorIn /DoorOut hotspots or via ChaneZone instructions. |
9 | Load | This zone is displayed while a new story is generated. |
10 | Goal | Goal zones are used for the final puzzles in each story. |
11 | Town / Spaceport | The starting zone on the main world. Every generated world has exactly one town. |
12 | Unknown | |
13 | Win | Shown when the game is won. This zone also displays the score. |
14 | Lose | This zone is shown after the hero has died. |
15 | Trade | A zone where the player has to trade items with an NPC to solve the puzzle. |
16 | Use | In order to solve this zone a tool must be used somewhere on the zone. |
17 | Find | Find zones provide an item without requiring anything else to solve them. |
18 | Find Unique Weapon | One of these will be placed close to the town. it provides a unique weapon (The Force in Yoda Stories) to the player. |
Additionally each zone provides lists of tiles that can be used to solve the puzzle, NPCs that can be used to trade with and tiles that the zone can drop when solved. In the world generation these items are chosen semi-randomly to create a new story every time.
On the world map neighboring zones can be visited by walking off the current zone. Additionally zones are connected through doors.
In order to make zones a little more interesting to play and replay, the game includes a custom scripting language. These actions are defined per zone.
Special points of interest on a zone are marked by hotspots. These locations mark doors, or places where an item can be used or an NPC be placed by the world generator.
In Yoda Stories, every zone belongs to one of the following planets:
Planet | Name | Description |
---|---|---|
1 | Tatooine | Desert planet, also referred to as Nevada |
2 | Hoth | Snowy ice planet, also referred to as Alaska |
3 | Endor | A forest planet, also referred to as Oregon |
5 | Dagobah | Swamp planet, used in the staring world |
Actions
Actions can make zones more interactive and dynamic. They are used for example to implement switches and in-game cut-scene animations. Each action is made up of a bunch of conditions and instructions that are executed if all conditions are satisfied.
See Scripting for a more detailed description of the internal scripting language.
Hotspots
Each hotspot has a position on the map, a type, and a single argument. Unless disabled, hotspots are triggered by placing an item, walking to the location or removing the tile at the object layer underneath the hotspot.
The following table describes the hotspot types and their purpose:
Type | Name | Description |
---|---|---|
0 | Drop Quest Item | |
1 | Spawn Location | |
2 | Drop Unique Weapon | |
3 | Vehicle To | Used in Travel Start zones, to change the zone to the travel target (identified by arg ). On the target zone, the hero will be placed at a corresponsing Vehicle Back hotspot. |
4 | Vehicle Back | |
5 | Drop Map | Drops the locator |
6 | Drop Item | Drops the item specified in arg when the object layer is free |
7 | NPC | A place where the puzzle NPC from arg can be placed. |
8 | Drop Weapon | Drops the weapon specified in arg |
9 | Door In | Connects the zone to the one in arg . |
10 | Door Out | A door leading back to the zone where the player came from |
11 | Unused | |
12 | Lock | This is a placeholder for a item in a use zone. Placing the correct item here removes the underlying tile from the object layer. |
13 | Teleporter | A place where the locator view is triggered for telportation |
14 | Ship From Planet | |
15 | Ship To Planet | Used on Dagobah to mark the place to switch worlds. The target zone on the main world is specified in arg . |
Monsters
TODO: Describe monster attributes, waypoints, drops, etc.
Scripting
The Desktop Adventures engine includes a binary scripting language. Each zone can have a number of actions. Each action consists of conditions and instructions.
Conditions and instructions have the following structure:
type Condition = {
opcode: number,
arguments: number[5],
text: string?
}
See Conditions and Instructions for a description of the known opcodes for conditions and instructions respectively.
Execution
Actions are evaluated on the current zone. Once every condition of an action is satisfied all instructions are executed. Consider this mock execution engine:
function execute(actions) {
for (const action of actions) {
if (action.conditions.every(condition => condition.isSatisfied()) {
for (const instruction of action.instructions) {
instruction.execute();
}
}
}
}
Registers
There are several registers available for use in scripts. All registers are local to the zone.
counter
– A simple16
-bit registersector-counter
–16
-bit register that is propagated to connected roomsrandom
–16
-bit register that can be set to random values
Conditions
The following is a list of condition opcodes used by Yoda Stories.
TODO: Check if Indy uses the same opcodes
Opcode | Name | # of arguments | Description |
---|---|---|---|
0x000 | ZoneNotInitialized | 0 | Evaluates to true exactly once (used for initialization) |
0x001 | ZoneEntered | 0 | Evaluates to true if hero just entered the zone |
0x002 | Bump | 3 | |
0x003 | PlacedItemIs | 5 | |
0x004 | StandingOn | 3 | Check if hero is at arg_0 xarg_1 and the floor tile is arg_2 |
0x005 | CounterIs | 1 | Current zone's counter value is equal to arg_0 |
0x006 | RandomIs | 1 | Current zone's random value is equal to arg_0 |
0x007 | RandomIsGreaterThan | 1 | Current zone's random value is greater than arg_0 |
0x008 | RandomIsLessThan | 1 | Current zone's random value is less than arg_0 |
0x009 | EnterByPlane | 0 | |
0x00a | TileAtIs | 4 | Check if tile at arg_0 xarg_1 xarg_2 is equal to arg_3 |
0x00b | MonsterIsDead | 1 | True if monster arg_0 is dead. |
0x00c | HasNoActiveMonsters | 0 | |
0x00d | HasItem | 1 | True if inventory contains arg_0 . If arg_0 is -1 check if inventory contains the item provided by the current zone's puzzle |
0x00e | RequiredItemIs | 1 | |
0x00f | EndingIs | 1 | True if arg_0 is equal to current goal item id |
0x010 | ZoneIsSolved | 0 | True if the current zone is solved |
0x011 | NoItemPlaced | 5 | Returns true if the user did not place an item |
0x012 | HasGoalItem | 0 | Returns true if the hero has the goal item |
0x013 | HealthIsLessThan | 1 | Hero's health is less than arg_0 . |
0x014 | HealthIsGreaterThan | 1 | Hero's health is greater than arg_0 . |
0x015 | Unused | 5 | |
0x016 | FindItemIs | 1 | True the item provided by current zone is arg_0 |
0x017 | PlacedItemIsNot | 5 | |
0x018 | HeroIsAt | 2 | True if hero's x/y position is args_0 xargs_1 . |
0x019 | SectorCounterIs | 1 | Current zone's sector-counter value is equal to arg_0 |
0x01a | SectorCounterIsLessThan | 1 | Current zone's sector-counter value is less than arg_0 |
0x01b | SectorCounterIsGreaterThan | 1 | Current zone's sector-counter value is greater than arg_0 |
0x01c | GamesWonIs | 1 | Total games won is equal to arg_0 |
0x01d | DropsQuestItemAt | 2 | |
0x01e | HasAnyRequiredItem | 0 | Determines if inventory contains any of the required items needed for current zone |
0x01f | CounterIsNot | 1 | Current zone's counter value is not equal to arg_0 |
0x020 | RandomIsNot | 1 | Current zone's random value is not equal to arg_0 |
0x021 | SectorCounterIsNot | 1 | Current zone's sector-counter value is not equal to arg_0 |
0x022 | IsVariable | 4 | Check if variable identified by arg_0 ⊕arg_1 ⊕arg_2 is set to arg_3 . Internally this is implemented as opcode 0x0a, check if tile at arg_0 xarg_1 xarg_2 is equal to arg_3 |
0x023 | GamesWonIsGreaterThan | 1 | Total games won is greater than arg_0 |
Instructions
The following is a list of instructions opcodes used by Yoda Stories.
TODO: Check if Indy uses the same opcodes
Opcode | Name | # of arguments | Description |
---|---|---|---|
0x000 | PlaceTile | 4 | Place tile arg_3 at arg_0 xarg_1 xarg_2 . To remove a tile the id -1 is used. |
0x001 | RemoveTile | 3 | Remove tile at arg_0 xarg_1 xarg_2 |
0x002 | MoveTile | 5 | Move Tile at arg_0 xarg_0 xarg_2 to arg_3 xarg_4 xarg_2 . Note that this can not be used to move tiles between layers! |
0x003 | DrawTile | 5 | |
0x004 | SpeakHero | 0 | Show speech bubble next to hero. Uses text attribute. |
0x005 | SpeakNpc | 2 | Show speech bubble at arg_0 xarg_1 . Uses text attribute. The characters ¢ and ¥ are used as placeholders for provided and required items of the current zone, respectively. |
0x006 | SetTileNeedsDisplay | 2 | Redraw tile at arg_0 xarg_1 |
0x007 | SetRectNeedsDisplay | 4 | Redraw the part of the current scene, specified by a rectangle positioned at arg_0 xarg_1 with width arg_2 and height arg_3 . |
0x008 | Wait | 0 | Pause script execution for one tick. |
0x009 | Redraw | 0 | Redraw the whole scene immediately |
0x00a | PlaySound | 1 | Play sound specified by arg_0 |
0x00b | StopSound | 0 | Stop playing sounds. _TODO: check if only music need to be stopped` |
0x00c | RollDice | 1 | Set current zone's random to a random value between 1 and arg_0 . |
0x00d | SetCounter | 1 | Set current zone's counter value to a arg_0 |
0x00e | AddToCounter | 1 | Add arg_0 to current zone's counter value |
0x00f | SetVariable | 4 | Set variable identified by arg_0 ⊕arg_1 ⊕arg_2 to arg_3 . Internally this is implemented as opcode 0x00, setting tile at arg_0 xarg_1 xarg_2 to arg_3 . |
0x010 | HideHero | 0 | Hide hero |
0x011 | ShowHero | 0 | Show hero |
0x012 | MoveHeroTo | 2 | Set hero's position to arg_0 xarg_1 ignoring impassable tiles. Execute hotspot actions, redraw the current scene and move camera if the hero is not hidden. |
0x013 | MoveHeroBy | 5 | |
0x014 | DisableAction | 0 | Disable current action |
0x015 | EnableHotspot | 1 | Enable hotspot arg_0 |
0x016 | DisableHotspot | 1 | Disable hotspot arg_0 |
0x017 | EnableMonster | 1 | Enable monster arg_0 |
0x018 | DisableMonster | 1 | Disable monster arg_0 |
0x019 | EnableAllMonsters | 0 | Enable all monsters |
0x01a | DisableAllMonsters | 0 | Disable all monsters |
0x01b | DropItem | 3 | Drops item arg_0 for pickup at arg_1 xarg_2 . If the item is -1, it drops the current sector's find item. instead |
0x01c | AddItem | 1 | Add item with id arg_0 to inventory |
0x01d | RemoveItem | 1 | Remove one instance of item arg_0 from the inventory |
0x01e | MarkAsSolved | 0 | |
0x01f | WinGame | 0 | |
0x020 | LoseGame | 0 | |
0x021 | ChangeZone | 3 | Change current zone to arg_0 . Hero will be placed at arg_1 xarg_2 in the new zone. |
0x022 | SetSectorCounter | 1 | Set current zone's sector-counter value to a arg_0 |
0x023 | AddToSectorCounter | 1 | Add arg_0 to current zone's sector-counter value |
0x024 | SetRandom | 1 | Set current zone's random value to a arg_0 |
0x025 | AddHealth | 1 | Increase hero's health by arg_0 . New health is capped at hero's max health (0x300). |
Score
At the end of each game a score called the Indy Quotient or Force Factor is calculated. The game keeps track of the last and highest scores in the ini file at C:/WINDOWS/Yodesk.ini
(see files/yodesk-ini.md) using the keys HScore
and LScore
, respectively.
The game combines four components to rate the player's performance:
- Time
- Solved puzzle ratio
- Difficulty
- Visited zones
Time:
const time = (baseTime in seconds + elapsedTime in seconds) / 60 - 5 * worldSize
if time <= 0 return 200
if 20 * time < 200
return 200 - 20 * time
return 0
Puzzles:
const solved = sectors.filter(zone => zone && zone.visited).length
return solved / worldSize * 100.0
Difficulty:
const solved = sectors.filter(zone => zone && zone.visited && zone.solved).length
const total = sectors.length
return solved / worldSize * 100.0
Visited Zones:
const solved = sectors.filter(zone => zone && zone.visited).length
return solved / worldSize * 100.0
Final Score:
return Sum(components)
Map Screen
In order for the player to find their way around the world and get some hints on how to solve the puzzles, the game includes a map screen. The screen can be accesses after the player finds the map (aka Locator) item.
TODO: Describe how locator texts are determined
Observations
Here are some observations about the map:
- The map scene uses 28x28 tiles instead of the usual 32x32
- Inventory allows opening the map by clicking any item that has Bits 7 and 20 set
- The map can be activated by hitting L on the keyboard
- Hints check tile attributes to determine if something is valuable, a tool, a part, etc.
R2D2 Help
When Luke first visits Dagobah his trusty companion R2-D2 is already waiting for him, ready to be picked up and help out.
R2D2 can be placed anywhere on the game screen and will try to give some information on whatever it was dropped on.
The messages given by R2 are stored as string resources in the executable.
The following string ids are used:
String | Hint | Description |
---|---|---|
57383 | AboutWalking | Chosen at random if no other message matches |
57384 | AboutFinding | Chosen at random if no other message matches |
57385 | About Using | Chosen at random if no other message matches |
57386 | About Weapons | Chosen at random if no other message matches |
57387 | AboutHealth | Chosen at random if no other message matches |
7382 | Yoda | Shown when placed on Yoda |
7395 | Hero | Shown when placed on Luke |
7388 | Vader | Shown when placed on Vader |
7398 | MedicalDroid | Shown when placed on medial droid |
7396 | TeleporterActive | Shown when placed on an active teleporter |
7397 | TeleporterInactive | Shown when placed on an inactive teleporter |
7380 | Draggable | Shown when placed on a tile with the Draggable flag |
7400 | Weapon | Show when placed on a tile with the Weapon flag |
7378 | Enemy | Shown when placed on a tile with the Character and Enemy flags |
7381 | NPC | Shown when placed on a tile with the Character and NPC attributes |
7391 | Ewok | Shown when placed on an Ewok |
7392 | Jawa | Shown when placed on a friendly Jawa |
7393 | Droid | Shown when placed on a droid (tile ids hard coded) |
7377 | X-Wing | Shown when placed on an X-Wing tile (not actually triggered) |
7376 | Storage | Shown when placed on a container (hard coded tile ids) |
7379 | Door | Show when placed on a door tile (hard coded list of tile ids) |
7389 | Win | Shown when game is won (can not be triggered) |
7390 | Lose | Shown when game is lost (can not be triggered) |
List of Storage Tile IDs
[0x102, 0x10, 0x48d, 0x279, 0x27b, 0x27c, 0x6e5]
List of Door IDs
[70, 71, 72, 73, 74, 75, 76, 145, 149, 152, 153, 220, 221, 223, 231, 232, 233, 350, 582, 584, 586, 588, 702, 709, 755, 756, 759, 760, 804, 806, 983, 984, 1047, 1048, 1081, 1112, 1120, 1259, 1461, 1462, 1472, 1473, 1539, 1544, 1858]
List of X-Wing Tile IDs
[0x3b4, 0x3b5, 0x3b6]
Cheats
On most websites for cheat codes you can find mentions of cheat codes like BLASTERS
and OBJECTS
that supposedly fill up the inventory with all items. These codes do not work and the executable does not even contain any reference to those codes.
Yoda Stories does however contain two cheat codes that actually work. To input them you have to activate the Locator
and type one of the codes. It is important to click the Locator
in the inventory instead of using the keyboard shortcut L
(the L
-key is interpreted as the first character of the cheat code).
After successfully entering a cheat code a message appears on the current zone.
Yoda Stories supports the following cheat codes:
Code | Message | Effect |
---|---|---|
gojedi | Super Jedi! | Adds 5 Thermal Detonators, a Blaster Rifle, a Blaster and The Force to the inventory. |
goyoda | Invincible! | The player's health is locked at the current value. Neither healing nor taking damage is possible. |
Indiana Jones and His Desktop Adventures does not have any cheat codes.
Files
This sections describes several custom or unusual file and binary formats used by the engine.
Yodesk.ini
Data that persists between launches of a Desktop Adventures game, like settings, highscore and information about the last generated worlds is stored in a ini-file.
Variant | Path |
---|---|
Yoda Stories | C:\Windows\Yodesk.ini |
Yoda Stories Demo | C:\Windows\YodaDemo.ini |
Indy's Adventures | C:\Windows\Deskadv.ini |
Indy's Demo |
The file is a standard INI file with the sections OPTIONS
, GameData
and Recent File List
.
The following is a sample file generated by Yoda Stories
:
[OPTIONS]
MIDILoad=1
PlaySound=0
PlayMusic=0
Difficulty=1
GameSpeed=140
WorldSize=1
Count=302
HScore=870
LScore=570
LCount=0
Terrain=2
[GameData]
Alaska0=2126634910,129,3,318,232,264
Nevada0=950869581,163,3,364,348,362
Options section
Key | Description |
---|---|
Settings | |
MIDILoad | |
PlaySound | Setting |
PlayMusic | Setting |
Difficulty | Setting, values range from |
GameSpeed | Setting, values range from |
WorldSize | Setting, values range from |
Score | |
Count | Number of worlds generated |
HScore | Highest score |
LScore | Last score |
LCount | Number of lost games |
World Generation | |
Terrain | Last terrain used to generate a world. The next world is determined based on this value. Since Indy's Adventures only have on terrain this value is not used. |
GameData section
The GameData
section is used to keep track of the end puzzles last used on each planet. When a new world on the planet is generated, these puzzles are excluded. This is supposed to increase variety between consecutive games so the player get different endings every time.
Each entry holds a comma separated list. The first entry is the last used PRNG seed, written out as a 32
-bit integer, eventhough only 16
-bits are used. The second number is a random value between 1
and 256
that is added to the puzzle ids. The third value is the number of puzzle ids, followed by the actual end puzzle ids that are to be excluded, each offset by the random value generated before.
Key | Mapping | Comment |
---|---|---|
Alaska | Yoda | Ice planet (Hoth) |
Nevada | Yoda | Desert planet (Tatooine) |
Oregon | Yoda | Forest planet (Endor) |
Hawaii | Indy | |
Wyoming | Indy |
Releases
It's hard to find a complete list of releases of Yoda Stories. MobyGames lists only two releases of the Windows version of the game - the US and a German version. The Star Wars Collectors Archive (SWCA) has additional information on releases from Japan, Taiwan, Italy and the Netherlands and there is a Spanish release version up on the internet archive.
If you know of any other releases please feel free to edit this page. And if you have access to a version that is not on the internet archive yet, please consider submitting it.
Release | Year | Publisher | Source |
---|---|---|---|
US | 1997 | LucasArts | MobyGames |
Germany | 1997 | FunSoft GmbH | MobyGames |
Spain | 1997 | Erbe Software | archive.org |
Japan | 1997 | Micro Mouse | SWCA |
Italy | 1997 | CTO | SWCA |
The Netherlands | 1997 | SWCA | |
Taiwan | 1997 | Unalis | SWCA |
The Patch
In February of '97 Lucas Arts released a patch called Yoda Update #6 that fixes problems in some zones. The Patch is a self-extracting archive that replaces the main game data file Yodesk.dta
with a new one.
A prompt saying zones #72, #236, #407, #474 and #572 have been fixed appears when the update is run.
The original release notes of yopatch6.exe
have been preserved by the Wayback Machine here (and with a different design here). They claim that in addition to the zone fixes "minor art modifications" have been made.
It would be interesting to find out what exactly has changed in the newer data file.
$ shasum yopatch6.exe
a8e18864184d49feaf0b74b93f60855f40ffe9bf yopatch6.exe
$ file yopatch6.exe
yopatch6.exe: PE32 executable (GUI) Intel 80386, for MS Windows
Zone 72
Zone #72 was one of the zones patch by update #6.
Zone 236
Zone #236 was one of the zones patch by update #6.
Zone 407
Zone #407 was one of the zones patch by update #6.
Zone 474
Zone #474 was one of the zones patch by update #6.
Zone 572
Zone #572 was one of the zones patch by update #6.
Trivia
Promotional Screenshots
After getting my hands on an actual retail copy of Yoda Stories I became curious of the screenshots shown on the back of the box. At first glance they seem to be captures of zones #95, #294 and #483. But after further inspection it's clear that none of the screenshots could have come from the final version of the game.
Zone #95 does not have any actions that could place Luke's X-Wing in the zone as shown in the screenshot.
Zone #294 is very close to the one depicted in the second screenshot, the only difference seems to be a missing crater tile next to Luke's head
The last screenshot was taken on a desert world. Zone #483 has very similar building and wall structures, but the dewback in the top left corner is missing.
I've created re-created the situation in each of the screenshots. They are available as downloads here, here and here.
Interestingly enough, the italian version of the box uses entirely different images that actually look like screenshots from the real game.
Left-over Debug Window
Checkout The Cutting Room Floor's entry on Yoda Stories for some more debug windows that are present in the program but can not be triggered.
Apart from the cheat codes there is a debug window that can be accessed using the key combination ctrl-F8
. A modal comes up that shows the current zone id, position and the id of this world's goal. The shortcut works in both Yoda Stories and Indiana Jones and his Desktop Adventures.
Yodesk.ksy
This is a machine-readable definition of the file format used by Yoda Stories. It can be used to generate a parser or inspect files online in the Kaitai Web IDE.
meta:
id: yodesk
application: "Star Wars: Yoda Stories"
file-extension: dta
license: CC0-1.0
ks-version: 0.9
endian: le
encoding: ASCII
doc: |
[Star Wars: Yoda Stories](https://en.wikipedia.org/wiki/Star_Wars:_Yoda_Stories) is a unique tile based game with procedurally
generated worlds.
This spec describes the file format used for all assets of the Windows
version of the game.
The file format follows the TLV (type-length-value) pattern to build a
central catalog containing the most important (and globally accessible)
assets of the game (e.g. puzzles, zones, tiles, etc.). The same pattern is
also found in some catalog entries to encode arrays of variable-length
structures.
With every new game, Yoda Stories generates a new world. This is done by
picking a random sample of puzzles from `PUZ2`. One of the chosen puzzles
will be the goal, which when solved wins the game.
Each puzzle provides an item when solved and some require one to be completed.
During world generation a global world map of 10x10 sectors is filled with
zones based on the selected puzzles.
To add variety and interactivity to each zone the game includes a simple
scripting engine. Zones can declare actions that when executed can for
example set, move or delete tiles, drop items or activate enemies.
seq:
- id: catalog
type: catalog_entry
repeat: until
repeat-until: _.type == "ENDF"
types:
catalog_entry:
seq:
- id: type
type: str
size: 4
- id: size
type: u4
if: type != "VERS" and type != "ZONE"
- id: content
type:
switch-on: type
cases:
'"VERS"': version
'"STUP"': startup_image
'"CHAR"': characters
'"CAUX"': character_auxiliaries
'"CHWP"': character_weapons
'"PUZ2"': puzzles
'"SNDS"': sounds
'"TILE"': tiles
'"TNAM"': tile_names
'"ZONE"': zones
'"TGEN"': tgen
'"ENDF"': endf
_: unknown_catalog_entry
unknown_catalog_entry:
seq:
- id: data
size: _parent.size
version:
seq:
- id: version
doc: Version of the file. This value is always set to 512.
type: u4
startup_image:
doc: |
A 288x288 bitmap to be shown while other assets are loaded and a new
world is generated.
seq:
- id: pixels
size: _parent.size
sounds:
doc: |
This section declares sounds used in the game. The actual audio data is
stored in wav files on the disk (in a directory named `sfx`) so this
section contains paths to each sound file.
Sounds can be referenced from the scripting language (see `play_sound`
instruction opcode below) and from weapon (see `character` structure).
Some sound ids (like the one when the hero is hit, or can't leave a
zone) are hard coded in the game.
seq:
- id: count
type: s2
- id: sounds
type: prefixed_strz
repeat: expr
repeat-expr: -count
tile_names:
seq:
- id: names
doc: |
List of tile ids and their corresponding names. These are shown in
the inventory or used in dialogs (see `speak_hero` and `speak_npc`
opcodes).
type: tile_name
repeat: until
repeat-until: _.tile_id == 0xFF_FF
tile_name:
seq:
- id: tile_id
type: u2
- id: name
type: strz
size: 0x18
if: tile_id != 0xFF_FF
tiles:
seq:
- id: tiles
type: tiles_entries
size: _parent.size
tiles_entries:
seq:
- id: tiles
type: tile
repeat: eos
tile:
seq:
- id: attributes
type: tile_attributes
size: 4
- id: pixels
size: 32 * 32
tile_attributes:
meta:
bit-endian: le
seq:
- id: has_transparency
type: b1
doc: |
Affects how tile image should be drawn. If set, the
value 0 in `pixels` is treated as transparent. Otherwise
it is drawn as black.
- id: is_floor
type: b1
doc: |
Tile is usually placed on the lowest layer of a zone
- id: is_object
type: b1
doc: |
Object, tile is usually placed on the middle layer of a zone
- id: is_draggable
type: b1
doc: |
If set and the tile is placed on the object layer it can be
dragged and pushed around by the hero.
- id: is_roof
type: b1
doc: |
Tile is usually placed on the top layer (roof)
- id: is_locator
type: b1
doc: |
Locator, tile is used in world map view overview
- id: is_weapon
type: b1
doc: |
Identifies tiles that are mapped to weapons
- id: is_item
type: b1
- id: is_character
type: b1
doc: |
Tile forms part of a character
- id: unused
type: b7
# Floor flags
- id: is_doorway
type: b1
doc: |
These tiles are doorways, monsters can't go
if: is_floor
# Locator flags
- id: unused1
type: b1
if: is_locator
- id: is_town
type: b1
doc: |
Marks the spaceport on the map
if: is_locator
- id: is_unsolved_puzzle
type: b1
doc: |
Marks a discovered, but unsolved puzzle on the map
if: is_locator
- id: is_solved_puzzle
type: b1
doc: |
Marks a solved puzzle on the map
if: is_locator
- id: is_unsolved_travel
type: b1
doc: |
Marks a place of travel on the map that has not been solved
if: is_locator
- id: is_solved_travel
type: b1
doc: |
Marks a solved place of travel on the map
if: is_locator
- id: is_unsolved_blockade_north
type: b1
doc: |
Marks a sector on the map that blocks access to northern zones
if: is_locator
- id: is_unsolved_blockade_south
type: b1
doc: |
Marks a sector on the map that blocks access to southern zones
if: is_locator
- id: is_unsolved_blockade_west
type: b1
doc: |
Marks a sector on the map that blocks access to western zones
if: is_locator
- id: is_unsolved_blockade_east
type: b1
doc: |
Marks a sector on the map that blocks access to eastern zones
if: is_locator
- id: is_solved_blockade_north
type: b1
doc: |
Marks a solved sector on the map that used to block access to
northern zones
if: is_locator
- id: is_solved_blockade_south
type: b1
doc: |
Marks a solved sector on the map that used to block access to
southern zones
if: is_locator
- id: is_solved_blockade_west
type: b1
doc: |
Marks a solved sector on the map that used to block access to
western zones
if: is_locator
- id: is_solved_blockade_east
type: b1
doc: |
Marks a solved sector on the map that used to block access to
eastern zones
if: is_locator
- id: is_unsolved_goal
type: b1
doc: |
The final puzzle of the world. Solving this wins the game
if: is_locator
- id: is_location_indicator
type: b1
doc: |
Overlay to mark the current position on the map
if: is_locator
# Item flags
- id: is_keycard
type: b1
if: is_item
- id: is_tool
type: b1
if: is_item
- id: is_part
type: b1
if: is_item
- id: is_valuable
type: b1
if: is_item
- id: is_map
type: b1
if: is_item
- id: unused2
type: b1
if: is_item
- id: is_edible
type: b1
if: is_item
# Weapon flags
- id: is_low_blaster
type: b1
doc: |
Item is a low intensity blaster (like the blaster pistol)
if: is_weapon
- id: is_high_blaster
type: b1
doc: |
Item is a high intensity blaster (like the blaster rifle)
if: is_weapon
- id: is_lightsaber
type: b1
if: is_weapon
- id: is_the_force
type: b1
if: is_weapon
# Character flags
- id: is_hero
type: b1
if: is_character
- id: is_enemy
type: b1
if: is_character
- id: is_npc
type: b1
if: is_character
action:
doc: |
Actions are the game's way to make static tile based maps more engaging
and interactive. Each action consists of zero or more conditions and
instructions, once all conditions are satisfied, all instructions are
executed in order.
To facilitate state, each zone has three 16-bit registers. These registers
are named `counter`, `shared-counter` and `random`. In addition to these
registers hidden tiles are sometimes used to mark state.
There are conditions and instructions to query and update these registers.
The `shared-counter` register is special in that it is shared between a
zone and it's rooms. Instruction `0xc` roll_dice can be used to set the
`random` register to a random value.
A naive implementation of the scripting engine could look like this:
```
for action in zone.actions:
all_conditions_satisfied = False
for condition in action.conditions:
all_conditions_satisfied = check(condition)
if !all_conditions_satisfied:
break
if !all_conditions_satisfied:
continue
for instruction in action.instructions:
execute(instruction)
```
See `condition_opcode` and `instruction_opcode` enums for a list of
available opcodes and their meanings.
seq:
- id: marker
contents: "IACT"
- id: size
type: u4
- id: num_conditions
type: u2
- id: conditions
type: condition
repeat: expr
repeat-expr: num_conditions
- id: num_instructions
type: u2
- id: instructions
type: instruction
repeat: expr
repeat-expr: num_instructions
condition:
seq:
- id: opcode
type: u2
enum: condition_opcode
- id: arguments
type: s2
repeat: expr
repeat-expr: 5
- id: len_text
type: u2
- id: text
type: str
size: len_text
doc: |
The `text_attribute` is never used, but seems to be included to
shared the type with instructions.
enums:
condition_opcode:
0x0:
id: zone_not_initialised
doc: Evaluates to true exactly once (used for initialisation)
0x1:
id: zone_entered
doc: Evaluates to true if hero just entered the zone
0x2:
id: bump
0x3:
id: placed_item_is
0x4:
id: standing_on
doc: |
Check if hero is at `args[0]`x`args[1]` and the floor tile is
`args[2]`
0x5:
id: counter_is
doc: Current zone's `counter` value is equal to `args[0]`
0x6:
id: random_is
doc: Current zone's `random` value is equal to `args[0]`
0x7:
id: random_is_greater_than
doc: Current zone's `random` value is greater than `args[0]`
0x8:
id: random_is_less_than
doc: Current zone's `random` value is less than `args[0]`
0x9:
id: enter_by_plane
0xa:
id: tile_at_is
doc: |
Check if tile at `args[0]`x`args[1]`x`args[2]` is equal to
`args[3]`
0xb:
id: monster_is_dead
doc: True if monster `args[0]` is dead.
0xc:
id: has_no_active_monsters
doc: undefined
0xd:
id: has_item
doc: |
True if inventory contains `args[0]`. If `args[0]` is `0xFFFF`
check if inventory contains the item provided by the current
zone's puzzle
0xe:
id: required_item_is
0xf:
id: ending_is
doc: True if `args[0]` is equal to current goal item id
0x10:
id: zone_is_solved
doc: True if the current zone is solved
0x11:
id: no_item_placed
doc: Returns true if the user did not place an item
0x12:
id: item_placed
doc: Returns true if the user placed an item
0x13:
id: health_is_less_than
doc: Hero's health is less than `args[0]`.
0x14:
id: health_is_greater_than
doc: Hero's health is greater than `args[0]`.
0x15: unused
0x16:
id: find_item_is
doc: True the item provided by current zone is `args[0]`
0x17:
id: placed_item_is_not
0x18:
id: hero_is_at
doc: True if hero's x/y position is `args_0`x`args_1`.
0x19:
id: shared_counter_is
doc: Current zone's `shared_counter` value is equal to `args[0]`
0x1a:
id: shared_counter_is_less_than
doc: Current zone's `shared_counter` value is less than `args[0]`
0x1b:
id: shared_counter_is_greater_than
doc: Current zone's `shared_counter` value is greater than `args[0]`
0x1c:
id: games_won_is
doc: Total games won is equal to `args[0]`
0x1d:
id: drops_quest_item_at
0x1e:
id: has_any_required_item
doc: |
Determines if inventory contains any of the required items needed
for current zone
0x1f:
id: counter_is_not
doc: Current zone's `counter` value is not equal to `args[0]`
0x20:
id: random_is_not
doc: Current zone's `random` value is not equal to `args[0]`
0x21:
id: shared_counter_is_not
doc: Current zone's `shared_counter` value is not equal to `args[0]`
0x22:
id: is_variable
doc: |
Check if variable identified by `args[0]`⊕`args[1]`⊕`args[2]` is
set to `args[3]`. Internally this is implemented as opcode 0x0a,
check if tile at `args[0]`x`args[1]`x`args[2]` is equal to
`args[3]`
0x23:
id: games_won_is_greater_than
doc: True, if total games won is greater than `args[0]`
instruction:
seq:
- id: opcode
type: u2
enum: instruction_opcode
- id: arguments
type: s2
repeat: expr
repeat-expr: 5
- id: len_text
type: u2
- id: text
type: str
size: len_text
enums:
instruction_opcode:
0x0:
id: place_tile
doc: |
Place tile `args[3]` at `args[0]`x`args[1]`x`args[2]`. To remove a
tile `args[3]` can be set to `0xFFFF`.
0x1:
id: remove_tile
doc: Remove tile at `args[0]`x`args[1]`x`args[2]`
0x2:
id: move_tile
doc: |
Move tile at `args[0]`x`args[0]`x`args[2]` to
`args[3]`x`args[4]`x`args[2]`. *Note that this can not be used to
move tiles between layers!*
0x3:
id: draw_tile
0x4:
id: speak_hero
doc: |
Show speech bubble next to hero. _Uses `text` attribute_.
Script execution is paused until the speech bubble is dismissed.
0x5:
id: speak_npc
doc: |
Show speech bubble at `args[0]`x`args[1]`. _Uses `text`
attribute_. The characters `¢` and `¥` are used as placeholders
for provided and required items of the current zone, respectively.
Script execution is paused until the speech bubble is dismissed.
0x6:
id: set_tile_needs_display
doc: Redraw tile at `args[0]`x`args[1]`
0x7:
id: set_rect_needs_display
doc: |
Redraw the part of the current scene, specified by a rectangle
positioned at `args[0]`x`args[1]` with width `args[2]` and height
`args[3]`.
0x8:
id: wait
doc: Pause script execution for one tick.
0x9:
id: redraw
doc: Redraw the whole scene immediately
0xa:
id: play_sound
doc: Play sound specified by `args[0]`
0xb:
id: stop_sound
doc: Stop playing sounds
0xc:
id: roll_dice
doc: |
Set current zone's `random` to a random value between 1 and
`args[0]`.
0xd:
id: set_counter
doc: Set current zone's `counter` value to a `args[0]`
0xe:
id: add_to_counter
doc: Add `args[0]` to current zone's `counter` value
0xf:
id: set_variable
doc: |
Set variable identified by `args[0]`⊕`args[1]`⊕`args[2]` to
`args[3]`. Internally this is implemented as opcode 0x00, setting
tile at `args[0]`x`args[1]`x`args[2]` to `args[3]`.
0x10:
id: hide_hero
doc: Hide hero
0x11:
id: show_hero
doc: Show hero
0x12:
id: move_hero_to
doc: |
Set hero's position to `args[0]`x`args[1]` ignoring impassable
tiles. Execute hotspot actions, redraw the current scene and move
camera if the hero is not hidden.
0x13:
id: move_hero_by
doc: |
Moves hero relative to the current location by `args[0]` in x and
`args[1]` in y direction.
0x14:
id: disable_action
doc: |
Disable current action, note that there's no way to activate the
action again.
0x15:
id: enable_hotspot
doc: Enable hotspot `args[0]` so it can be triggered.
0x16:
id: disable_hotspot
doc: Disable hotspot `args[0]` so it can't be triggered anymore.
0x17:
id: enable_monster
doc: Enable monster `args[0]`
0x18:
id: disable_monster
doc: Disable monster `args[0]`
0x19:
id: enable_all_monsters
doc: Enable all monsters
0x1a:
id: disable_all_monsters
doc: Disable all monsters
0x1b:
id: drop_item
doc: |
Drops item `args[0]` for pickup at `args[1]`x`args[2]`. If the
item is 0xFFFF, it drops the current sector's find item instead.
Script execution is paused until the item is picked up.
0x1c:
id: add_item
doc: Add tile with id `args[0]` to inventory
0x1d:
id: remove_item
doc: Remove one instance of item `args[0]` from the inventory
0x1e:
id: mark_as_solved
doc: |
Marks current sector solved for the overview map.
0x1f:
id: win_game
doc: Ends the current story by winning.
0x20:
id: lose_game
doc: Ends the current story by losing.
0x21:
id: change_zone
doc: |
Change current zone to `args[0]`. Hero will be placed at
`args[1]`x`args[2]` in the new zone.
0x22:
id: set_shared_counter
doc: Set current zone's `shared_counter` value to a `args[0]`
0x23:
id: add_to_shared_counter
doc: Add `args[0]` to current zone's `shared_counter` value
0x24:
id: set_random
doc: Set current zone's `random` value to a `args[0]`
0x25:
id: add_health
doc: |
Increase hero's health by `args[0]`. New health is capped at
hero's max health (0x300). Argument 0 can also be negative
subtract from hero's health.
monster:
doc: A monster is a enemy in a zone.
seq:
- id: character
type: u2
- id: x
type: u2
- id: y
type: u2
- id: loot
doc: |
References the item (loot - 1) that will be dropped if the monster
is killed. If set to `0xFFFF` the current zone's quest item will be
dropped.
type: u2
- id: drops_loot
doc: If this field is anything other than 0 the monster may drop an
item when killed.
type: u4
- id: waypoints
type: waypoint
repeat: expr
repeat-expr: 4
zone:
seq:
- id: planet
doc: |
Planet this zone can be placed on.
During world generation the goal puzzle dictates which planet is
chosen. Apart from `swamp` zones, only the zones with type `empty`
or the chosen type are loaded when a game is in progress.
type: u2
enum: planet
- id: size
type: u4
- id: index
type: u2
- id: marker
contents: "IZON"
- id: size2
type: u4
- id: width
doc: Width of the zone in tiles. Either 9 or 18.
type: u2
- id: height
doc: Height of the zone in tiles. Either 9 or 18.
type: u2
- id: type
enum: zone_type
type: u4
- id: shared_counter
doc: |
Scripting register shared between the zone and its rooms.
type: u2
valid: 0xFF_FF
- id: planet_again
doc: Repetition of the `planet` field
type: u2
- id: tile_ids
type: zone_spot
repeat: expr
repeat-expr: width * height
doc: |
`tile_ids` is made up of three interleaved tile layers ordered from
bottom (floor) to top (roof).
Tiles are often references via 3 coordinates (xyz), which
corresponds to an index into this array calculated as `n = y * width
* 3 + x * 3 = z`.
- id: num_hotspots
type: u2
- id: hotspots
type: hotspot
repeat: expr
repeat-expr: num_hotspots
- id: izax
type: zone_auxiliary
- id: izx2
type: zone_auxiliary_2
- id: izx3
type: zone_auxiliary_3
- id: izx4
type: zone_auxiliary_4
- id: num_actions
type: u2
- id: actions
type: action
repeat: expr
repeat-expr: num_actions
enums:
planet:
0: none
1: desert
2: snow
3: forest
5: swamp
zone_type:
0:
id: none
1:
id: empty
doc: |
Empty zones do not contain a puzzle to be solved and are used to
fill the space between between zones that are relevant for winning
the game.
2:
id: blockade_north
doc: |
This type of zone blocks access to sectors north of it until the
puzzle is solved.
3:
id: blockade_south
doc: |
This type of zone blocks access to sectors south of it until the
puzzle is solved.
4:
id: blockade_east
doc: |
This type of zone blocks access to sectors east of it until the
puzzle is solved.
5:
id: blockade_west
doc: |
This type of zone blocks access to sectors west of it until the
puzzle is solved.
6:
id: travel_start
doc: |
Starting point to travel to an island on the edge of the world.
`travel_start` and `travel_end` zones are connected through
hotspot of type `vehicle_to` and `vehicle_back`.
7:
id: travel_end
doc: |
Travel target that is only placed on an island at the edge of the
world map during world generation.
8:
id: room
doc: |
A zone that can not be placed on the world map directly. Instead
rooms are accessed via actions or hotspots of type `door_in`. They
usually contain at least one `door_out` hotspot to get back to the
other zone.
9:
id: load
doc: |
This type of zone is shown after the game has loaded all assets.
It should resemble the image from the catalog entry of type
`startup_image` for a smooth transition from loading to game play.
10:
id: goal
doc: |
Every world contains exactly one goal zone. Solving this zone wins
the game.
11:
id: town
doc: |
This is the entry zone where the hero arrives after leaving the
swamp planet. Each planet can only have one town zone.
13:
id: win
doc: |
Shown when a game is won. The score is rendered above the tiles at
coordinates 5x7 and 6x7.
14:
id: lose
doc: |
Shown when a game is lost.
15:
id: trade
doc: |
In order to solve this zone and gain a new item the hero has to
trade something in.
16:
id: use
doc: |
This type of zone can be solved by making applying a tool or using
a keycard.
17:
id: find
doc: |
This type of zone can be solved without using items.
18:
id: find_unique_weapon
doc: |
This zone provides the hero with a unique weapon and will be
placed closed to a town zone.
zone_spot:
seq:
- id: column
doc: from bottom to top, 0xFFFF indicates empty tiles
type: u2
repeat: expr
repeat-expr: 3
hotspot:
doc: |
In addition to actions some puzzles and events are triggered by
hotspots. These hotspots are triggered when the hero steps on them or
places an item at the location. Additionally, hotspots are used during
world generation to mark places where NPCs can spawn.
seq:
- id: type
type: u4
enum: hotspot_type
- id: x
type: u2
- id: y
type: u2
- id: enabled
doc: |
If disabled, hotspots can not be triggered. See instruction opcodes
called `enable_hotspot` and `disable_hotspot`.
type: u2
- id: argument
type: u2
enums:
hotspot_type:
0:
id: drop_quest_item
doc: |
Drops the item provided by the zone when solved. Can be set to a
specific item, or to `0xFFFF` to use the one from the currently
assigned puzzle.
1:
id: spawn_location
doc: |
Possible spawn location for one of the zone's NPCs.
2:
id: drop_unique_weapon
doc: |
Hotspot that drops the unique weapon found in zones of type
`find_unique_weapon`.
3:
id: vehicle_to
doc: |
Used in `travel_start` zones as a trigger to teleport to the
corresponding `travel_end` zone. The hotspot argument contains the
id of the zone to teleport to.
4:
id: vehicle_back
doc: |
Counter part to `vehicle_to` hotspots. This is used to determine
the hero's position on the zone after the `vehicle_to` hotspot has
been triggered and to teleport back to the zone on main land.
5:
id: drop_map
doc: |
Hotspot that drops the map (aka locator) tile. One `find` zone
with a hotspot of this type will be placed next to a town during
world generation.
6:
id: drop_item
doc: |
Hotspot that, when triggered drops the item specified in the
hotspot's argument. If the item is set to `0xFFFF` the zone's
quest item will be dropped.
7:
id: npc
doc: |
This seems to be a placeholder for a pre-assigned NPC.
8:
id: drop_weapon
doc: |
Drops a weapon (specified by the hotspot argument) when triggered.
9:
id: door_in
doc: |
When triggered this hotspot type move the hero to the zone
specified in the hotspot argument. The hero's location on the new
zone will be determined by a corresponding `door_out` hotspot in
the target zone.
10:
id: door_out
doc: |
Determines where the hero will be placed when the zone is entered
through a door. When triggered, this transports the player back to
the `door_in` hotspot they game from.
11: unused
12: lock
13:
id: teleporter
doc: |
Teleporter hotspots can be used to instantly teleport to other
(visited) teleporters on the map
14:
id: ship_to_planet
doc: |
Behaves similar to the `vehicle_to` hotspot type but travels
between the town and the swamp planet.
15:
id: ship_from_planet
doc: |
Behaves similar to the `vehicle_back` hotspot type but travels
between the town and the swamp planet.
zone_auxiliary:
seq:
- id: marker
contents: "IZAX"
- id: size
type: u4
- type: u2
- id: num_monsters
type: u2
- id: monsters
type: monster
repeat: expr
repeat-expr: num_monsters
- id: num_required_items
type: u2
- id: required_items
doc: List of items that can be used to solve the zone.
type: u2
repeat: expr
repeat-expr: num_required_items
- id: num_goal_items
type: u2
- id: goal_items
doc: |
Additional items that are needed to solve the zone. Only used if the
zone type is `goal`.
type: u2
repeat: expr
repeat-expr: num_goal_items
zone_auxiliary_2:
seq:
- id: marker
contents: "IZX2"
- id: size
type: u4
- id: num_provided_items
type: u2
- id: provided_items
doc: Items that can be gained when the zone is solved.
type: u2
repeat: expr
repeat-expr: num_provided_items
zone_auxiliary_3:
seq:
- id: marker
contents: "IZX3"
- id: size
type: u4
- id: num_npcs
type: u2
- id: npcs
doc: |
NPCs that can be placed in the zone to trade items with the hero.
type: u2
repeat: expr
repeat-expr: num_npcs
zone_auxiliary_4:
seq:
- id: marker
contents: "IZX4"
- id: size
type: u4
- type: u2
zones:
seq:
- id: num_zones
type: u2
- id: zones
type: zone
repeat: expr
repeat-expr: num_zones
puzzles:
seq:
- id: puzzles
type: puzzle
repeat: until
repeat-until: _.index == 0xFF_FF
puzzle:
seq:
- id: index
type: u2
- id: marker
if: index != 0xFF_FF
contents: "IPUZ"
- id: size
type: u4
if: index != 0xFF_FF
- id: type
type: u4
if: index != 0xFF_FF
- id: item1_class
type: u4
enum: puzzle_item_class
if: index != 0xFF_FF
- id: item2_class
type: u4
enum: puzzle_item_class
if: index != 0xFF_FF
- type: u2
if: index != 0xFF_FF
- id: strings
type: prefixed_str
repeat: expr
repeat-expr: 5
if: index != 0xFF_FF
- id: item_1
type: u2
if: index != 0xFF_FF
- id: item_2
type: u2
if: index != 0xFF_FF
enums:
puzzle_item_class:
0: keycard
1: tool
2: part
4: valuable
0xFFFF_FFFF: none
endf:
seq: []
tgen:
doc: |
The TGEN section is only present in non-english versions of the game. It's purpose or
internal structure is unknown.
seq:
- id: data
size: _parent.size
characters:
seq:
- id: characters
type: character
repeat: until
repeat-until: _.index == 0xFF_FF
character:
seq:
- id: index
type: u2
- id: marker
contents: "ICHA"
if: index != 0xFF_FF
- id: size
type: u4
if: index != 0xFF_FF
- id: name
type: strz
size: 16
if: index != 0xFF_FF
- id: type
type: u2
enum: character_type
if: index != 0xFF_FF
- id: movement_type
type: u2
enum: movement_type
if: index != 0xFF_FF
- id: probably_garbage_1
type: u2
if: index != 0xFF_FF
- id: probably_garbage_2
type: u4
if: index != 0xFF_FF
- id: frame_1
type: char_frame
if: index != 0xFF_FF
- id: frame_2
type: char_frame
if: index != 0xFF_FF
- id: frame_3
type: char_frame
if: index != 0xFF_FF
enums:
character_type:
1: hero
2: enemy
4: weapon
movement_type:
0: none
4: sit
9: wander
10: patrol
12: animation
char_frame:
seq:
- id: tiles
type: u2
repeat: expr
repeat-expr: 0x8
character_auxiliaries:
seq:
- id: auxiliaries
type: character_auxiliary
repeat: until
repeat-until: _.index == 0xFF_FF
character_auxiliary:
seq:
- id: index
type: u2
- id: damage
type: s2
if: index != 0xFF_FF
character_weapons:
seq:
- id: weapons
type: character_weapon
repeat: until
repeat-until: _.index == 0xFF_FF
character_weapon:
seq:
- id: index
type: u2
- id: reference
doc: |
If the character referenced by index is a monster, this is a
reference to their weapon, otherwise this is the index of the
weapon's sound
type: u2
if: index != 0xFF_FF
- id: health
type: u2
if: index != 0xFF_FF
# Utilities
prefixed_str:
seq:
- id: len_content
type: u2
- id: content
type: str
size: len_content
prefixed_strz:
seq:
- id: len_content
type: u2
- id: content
type: strz
size: len_content
waypoint:
seq:
- id: x
type: u4
- id: y
type: u4
Deskadv.ksy
This is a machine-readable definition of the file format used by Indiana Jones and His Desktop Adventures. It can be used to generate a parser or inspect files online in the Kaitai Web IDE.
meta:
id: deskadv
application: "Indiana Jones and His Desktop Adventures"
file-extension: daw
license: CC0-1.0
ks-version: 0.9
endian: le
encoding: ISO-8859-2
seq:
- id: catalog
type: catalog_entry
repeat: until
repeat-until: _.type == "ENDF"
types:
catalog_entry:
seq:
- id: type
type: str
size: 4
- id: size
type: u4
if: type != "VERS"
- id: content
type:
switch-on: type
cases:
'"VERS"': version
'"STUP"': startup_image
'"CHAR"': characters
'"CAUX"': character_auxiliaries
'"CHWP"': character_weapons
'"PUZ2"': puzzles
'"SNDS"': sounds
'"TILE"': tiles
'"TNAM"': tile_names
'"ANAM"': action_names
'"PNAM"': puzzle_names
'"ZNAM"': zone_names
'"HTSP"': hotspots
'"ACTN"': actions
'"ZONE"': zones
'"ZAUX"': zones_aux_1
'"ZAX2"': zones_aux_2
'"ZAX3"': zones_aux_3
'"ZAX4"': zones_aux_4
'"TGEN"': tgen
'"ENDF"': endf
_: unknown_catalog_entry
unknown_catalog_entry:
seq:
- id: data
size: _parent.size
version:
seq:
- id: version
doc: Version of the file. This value is always set to 512.
type: u4
startup_image:
doc: |
A 288x288 bitmap to be shown while other assets are loaded and a new
world is generated.
seq:
- id: pixels
size: _parent.size
sounds:
doc: |
This section declares sounds used in the game. The actual audio data is
stored in wav files on the disk (in a directory named `sfx`) so this
section contains paths to each sound file.
Sounds can be referenced from the scripting language (see `play_sound`
instruction opcode below) and from weapon (see `character` structure).
Some sound ids (like the one when the hero is hit, or can't leave a
zone) are hard coded in the game.
seq:
- id: count
type: s2
- id: sounds
type: prefixed_strz
repeat: expr
repeat-expr: -count
tile_names:
seq:
- id: names
doc: |
List of tile ids and their corresponding names. These are shown in
the inventory or used in dialogs (see `speak_hero` and `speak_npc`
opcodes).
type: tile_name
repeat: until
repeat-until: _.tile_id == 0xFF_FF
tile_name:
seq:
- id: tile_id
type: u2
- id: name
type: strz
size: 0x10
if: tile_id != 0xFF_FF
tiles:
seq:
- id: tiles
type: tiles_entries
size: _parent.size
tiles_entries:
seq:
- id: tiles
type: tile
repeat: eos
tile:
seq:
- id: attributes
type: tile_attributes
size: 4
- id: pixels
size: 32 * 32
tile_attributes:
meta:
bit-endian: le
seq:
- id: has_transparency
type: b1
doc: |
Affects how tile image should be drawn. If set, the
value 0 in `pixels` is treated as transparent. Otherwise
it is drawn as black.
- id: is_floor
type: b1
doc: |
Tile is usually placed on the lowest layer of a zone
- id: is_object
type: b1
doc: |
Object, tile is usually placed on the middle layer of a zone
- id: is_draggable
type: b1
doc: |
If set and the tile is placed on the object layer it can be
dragged and pushed around by the hero.
- id: is_roof
type: b1
doc: |
Tile is usually placed on the top layer (roof)
- id: is_locator
type: b1
doc: |
Locator, tile is used in world map view overview
- id: is_weapon
type: b1
doc: |
Identifies tiles that are mapped to weapons
- id: is_item
type: b1
- id: is_character
type: b1
doc: |
Tile forms part of a character
- id: unused
type: b7
# Floor flags
- id: is_doorway
type: b1
doc: |
These tiles are doorways, monsters can't go
if: is_floor
# Locator flags
- id: unused1
type: b1
if: is_locator
- id: is_town
type: b1
doc: |
Marks the spaceport on the map
if: is_locator
- id: is_unsolved_puzzle
type: b1
doc: |
Marks a discovered, but unsolved puzzle on the map
if: is_locator
- id: is_solved_puzzle
type: b1
doc: |
Marks a solved puzzle on the map
if: is_locator
- id: is_unsolved_travel
type: b1
doc: |
Marks a place of travel on the map that has not been solved
if: is_locator
- id: is_solved_travel
type: b1
doc: |
Marks a solved place of travel on the map
if: is_locator
- id: is_unsolved_blockade_north
type: b1
doc: |
Marks a sector on the map that blocks access to northern zones
if: is_locator
- id: is_unsolved_blockade_south
type: b1
doc: |
Marks a sector on the map that blocks access to southern zones
if: is_locator
- id: is_unsolved_blockade_west
type: b1
doc: |
Marks a sector on the map that blocks access to western zones
if: is_locator
- id: is_unsolved_blockade_east
type: b1
doc: |
Marks a sector on the map that blocks access to eastern zones
if: is_locator
- id: is_solved_blockade_north
type: b1
doc: |
Marks a solved sector on the map that used to block access to
northern zones
if: is_locator
- id: is_solved_blockade_south
type: b1
doc: |
Marks a solved sector on the map that used to block access to
southern zones
if: is_locator
- id: is_solved_blockade_west
type: b1
doc: |
Marks a solved sector on the map that used to block access to
western zones
if: is_locator
- id: is_solved_blockade_east
type: b1
doc: |
Marks a solved sector on the map that used to block access to
eastern zones
if: is_locator
- id: is_unsolved_goal
type: b1
doc: |
The final puzzle of the world. Solving this wins the game
if: is_locator
- id: is_location_indicator
type: b1
doc: |
Overlay to mark the current position on the map
if: is_locator
# Item flags
- id: is_keycard
type: b1
if: is_item
- id: is_tool
type: b1
if: is_item
- id: is_part
type: b1
if: is_item
- id: is_valuable
type: b1
if: is_item
- id: is_map
type: b1
if: is_item
- id: unused2
type: b1
if: is_item
- id: is_edible
type: b1
if: is_item
# Weapon flags
- id: is_low_blaster
type: b1
doc: |
Item is a low intensity blaster (like the blaster pistol)
if: is_weapon
- id: is_high_blaster
type: b1
doc: |
Item is a high intensity blaster (like the blaster rifle)
if: is_weapon
- id: is_lightsaber
type: b1
if: is_weapon
- id: is_the_force
type: b1
if: is_weapon
# Character flags
- id: is_hero
type: b1
if: is_character
- id: is_enemy
type: b1
if: is_character
- id: is_npc
type: b1
if: is_character
action:
doc: |
Actions are the game's way to make static tile based maps more engaging
and interactive. Each action consists of zero or more conditions and
instructions, once all conditions are satisfied, all instructions are
executed in order.
To facilitate state, each zone has three 16-bit registers. These registers
are named `counter`, `shared-counter` and `random`. In addition to these
registers hidden tiles are sometimes used to mark state.
There are conditions and instructions to query and update these registers.
The `shared-counter` register is special in that it is shared between a
zone and it's rooms. Instruction `0xc` roll_dice can be used to set the
`random` register to a random value.
A naive implementation of the scripting engine could look like this:
```
for action in zone.actions:
all_conditions_satisfied = False
for condition in action.conditions:
all_conditions_satisfied = check(condition)
if !all_conditions_satisfied:
break
if !all_conditions_satisfied:
continue
for instruction in action.instructions:
execute(instruction)
```
See `condition_opcode` and `instruction_opcode` enums for a list of
available opcodes and their meanings.
seq:
- id: marker
contents: "IACT"
- id: size
type: u4
- id: num_conditions
type: u2
- id: conditions
type: condition
repeat: expr
repeat-expr: num_conditions
- id: num_instructions
type: u2
- id: instructions
type: instruction
repeat: expr
repeat-expr: num_instructions
condition:
seq:
- id: opcode
type: u2
enum: condition_opcode
- id: arguments
type: s2
repeat: expr
repeat-expr: 5
- id: len_text
type: u2
- id: text
type: str
size: len_text
doc: |
The `text_attribute` is never used, but seems to be included to
shared the type with instructions.
enums:
condition_opcode:
0x0:
id: zone_not_initialised
doc: Evaluates to true exactly once (used for initialisation)
0x1:
id: zone_entered
doc: Evaluates to true if hero just entered the zone
0x2:
id: bump
0x3:
id: placed_item_is
0x4:
id: standing_on
doc: |
Check if hero is at `args[0]`x`args[1]` and the floor tile is
`args[2]`
0x5:
id: counter_is
doc: Current zone's `counter` value is equal to `args[0]`
0x6:
id: random_is
doc: Current zone's `random` value is equal to `args[0]`
0x7:
id: random_is_greater_than
doc: Current zone's `random` value is greater than `args[0]`
0x8:
id: random_is_less_than
doc: Current zone's `random` value is less than `args[0]`
0x9:
id: enter_by_plane
0xa:
id: tile_at_is
doc: |
Check if tile at `args[0]`x`args[1]`x`args[2]` is equal to
`args[3]`
0xb:
id: monster_is_dead
doc: True if monster `args[0]` is dead.
0xc:
id: has_no_active_monsters
doc: undefined
0xd:
id: has_item
doc: |
True if inventory contains `args[0]`. If `args[0]` is `0xFFFF`
check if inventory contains the item provided by the current
zone's puzzle
0xe:
id: required_item_is
0xf:
id: ending_is
doc: True if `args[0]` is equal to current goal item id
0x10:
id: zone_is_solved
doc: True if the current zone is solved
0x11:
id: no_item_placed
doc: Returns true if the user did not place an item
0x12:
id: item_placed
doc: Returns true if the user placed an item
0x13:
id: health_is_less_than
doc: Hero's health is less than `args[0]`.
0x14:
id: health_is_greater_than
doc: Hero's health is greater than `args[0]`.
0x15: unused
0x16:
id: find_item_is
doc: True the item provided by current zone is `args[0]`
0x17:
id: placed_item_is_not
0x18:
id: hero_is_at
doc: True if hero's x/y position is `args_0`x`args_1`.
0x19:
id: shared_counter_is
doc: Current zone's `shared_counter` value is equal to `args[0]`
0x1a:
id: shared_counter_is_less_than
doc: Current zone's `shared_counter` value is less than `args[0]`
0x1b:
id: shared_counter_is_greater_than
doc: Current zone's `shared_counter` value is greater than `args[0]`
0x1c:
id: games_won_is
doc: Total games won is equal to `args[0]`
0x1d:
id: drops_quest_item_at
0x1e:
id: has_any_required_item
doc: |
Determines if inventory contains any of the required items needed
for current zone
0x1f:
id: counter_is_not
doc: Current zone's `counter` value is not equal to `args[0]`
0x20:
id: random_is_not
doc: Current zone's `random` value is not equal to `args[0]`
0x21:
id: shared_counter_is_not
doc: Current zone's `shared_counter` value is not equal to `args[0]`
0x22:
id: is_variable
doc: |
Check if variable identified by `args[0]`⊕`args[1]`⊕`args[2]` is
set to `args[3]`. Internally this is implemented as opcode 0x0a,
check if tile at `args[0]`x`args[1]`x`args[2]` is equal to
`args[3]`
0x23:
id: games_won_is_greater_than
doc: True, if total games won is greater than `args[0]`
instruction:
seq:
- id: opcode
type: u2
enum: instruction_opcode
- id: arguments
type: s2
repeat: expr
repeat-expr: 5
- id: len_text
type: u2
- id: text
type: str
size: len_text
enums:
instruction_opcode:
0x0:
id: place_tile
doc: |
Place tile `args[3]` at `args[0]`x`args[1]`x`args[2]`. To remove a
tile `args[3]` can be set to `0xFFFF`.
0x1:
id: remove_tile
doc: Remove tile at `args[0]`x`args[1]`x`args[2]`
0x2:
id: move_tile
doc: |
Move tile at `args[0]`x`args[0]`x`args[2]` to
`args[3]`x`args[4]`x`args[2]`. *Note that this can not be used to
move tiles between layers!*
0x3:
id: draw_tile
0x4:
id: speak_hero
doc: |
Show speech bubble next to hero. _Uses `text` attribute_.
Script execution is paused until the speech bubble is dismissed.
0x5:
id: speak_npc
doc: |
Show speech bubble at `args[0]`x`args[1]`. _Uses `text`
attribute_. The characters `¢` and `¥` are used as placeholders
for provided and required items of the current zone, respectively.
Script execution is paused until the speech bubble is dismissed.
0x6:
id: set_tile_needs_display
doc: Redraw tile at `args[0]`x`args[1]`
0x7:
id: set_rect_needs_display
doc: |
Redraw the part of the current scene, specified by a rectangle
positioned at `args[0]`x`args[1]` with width `args[2]` and height
`args[3]`.
0x8:
id: wait
doc: Pause script execution for one tick.
0x9:
id: redraw
doc: Redraw the whole scene immediately
0xa:
id: play_sound
doc: Play sound specified by `args[0]`
0xb:
id: stop_sound
doc: Stop playing sounds
0xc:
id: roll_dice
doc: |
Set current zone's `random` to a random value between 1 and
`args[0]`.
0xd:
id: set_counter
doc: Set current zone's `counter` value to a `args[0]`
0xe:
id: add_to_counter
doc: Add `args[0]` to current zone's `counter` value
0xf:
id: set_variable
doc: |
Set variable identified by `args[0]`⊕`args[1]`⊕`args[2]` to
`args[3]`. Internally this is implemented as opcode 0x00, setting
tile at `args[0]`x`args[1]`x`args[2]` to `args[3]`.
0x10:
id: hide_hero
doc: Hide hero
0x11:
id: show_hero
doc: Show hero
0x12:
id: move_hero_to
doc: |
Set hero's position to `args[0]`x`args[1]` ignoring impassable
tiles. Execute hotspot actions, redraw the current scene and move
camera if the hero is not hidden.
0x13:
id: move_hero_by
doc: |
Moves hero relative to the current location by `args[0]` in x and
`args[1]` in y direction.
0x14:
id: disable_action
doc: |
Disable current action, note that there's no way to activate the
action again.
0x15:
id: enable_hotspot
doc: Enable hotspot `args[0]` so it can be triggered.
0x16:
id: disable_hotspot
doc: Disable hotspot `args[0]` so it can't be triggered anymore.
0x17:
id: enable_monster
doc: Enable monster `args[0]`
0x18:
id: disable_monster
doc: Disable monster `args[0]`
0x19:
id: enable_all_monsters
doc: Enable all monsters
0x1a:
id: disable_all_monsters
doc: Disable all monsters
0x1b:
id: drop_item
doc: |
Drops item `args[0]` for pickup at `args[1]`x`args[2]`. If the
item is 0xFFFF, it drops the current sector's find item instead.
Script execution is paused until the item is picked up.
0x1c:
id: add_item
doc: Add tile with id `args[0]` to inventory
0x1d:
id: remove_item
doc: Remove one instance of item `args[0]` from the inventory
0x1e:
id: mark_as_solved
doc: |
Marks current sector solved for the overview map.
0x1f:
id: win_game
doc: Ends the current story by winning.
0x20:
id: lose_game
doc: Ends the current story by losing.
0x21:
id: change_zone
doc: |
Change current zone to `args[0]`. Hero will be placed at
`args[1]`x`args[2]` in the new zone.
0x22:
id: set_shared_counter
doc: Set current zone's `shared_counter` value to a `args[0]`
0x23:
id: add_to_shared_counter
doc: Add `args[0]` to current zone's `shared_counter` value
0x24:
id: set_random
doc: Set current zone's `random` value to a `args[0]`
0x25:
id: add_health
doc: |
Increase hero's health by `args[0]`. New health is capped at
hero's max health (0x300). Argument 0 can also be negative
subtract from hero's health.
monster:
doc: A monster is a enemy in a zone.
seq:
- id: character
type: u2
- id: x
type: u2
- id: y
type: u2
zone:
seq:
- id: marker
contents: "IZON"
- id: size2
type: u4
- id: width
doc: Width of the zone in tiles. Either 9 or 18.
type: u2
- id: height
doc: Height of the zone in tiles. Either 9 or 18.
type: u2
- id: type
enum: zone_type
type: u4
- id: tile_ids
type: zone_spot
repeat: expr
repeat-expr: width * height
doc: |
`tile_ids` is made up of three interleaved tile layers ordered from
bottom (floor) to top (roof).
Tiles are often references via 3 coordinates (xyz), which
corresponds to an index into this array calculated as `n = y * width
* 3 + x * 3 = z`.
enums:
planet:
0: none
1: desert
2: snow
3: forest
5: swamp
zone_type:
0:
id: none
1:
id: empty
doc: |
Empty zones do not contain a puzzle to be solved and are used to
fill the space between between zones that are relevant for winning
the game.
2:
id: blockade_north
doc: |
This type of zone blocks access to sectors north of it until the
puzzle is solved.
3:
id: blockade_south
doc: |
This type of zone blocks access to sectors south of it until the
puzzle is solved.
4:
id: blockade_east
doc: |
This type of zone blocks access to sectors east of it until the
puzzle is solved.
5:
id: blockade_west
doc: |
This type of zone blocks access to sectors west of it until the
puzzle is solved.
6:
id: travel_start
doc: |
Starting point to travel to an island on the edge of the world.
`travel_start` and `travel_end` zones are connected through
hotspot of type `vehicle_to` and `vehicle_back`.
7:
id: travel_end
doc: |
Travel target that is only placed on an island at the edge of the
world map during world generation.
8:
id: room
doc: |
A zone that can not be placed on the world map directly. Instead
rooms are accessed via actions or hotspots of type `door_in`. They
usually contain at least one `door_out` hotspot to get back to the
other zone.
9:
id: load
doc: |
This type of zone is shown after the game has loaded all assets.
It should resemble the image from the catalog entry of type
`startup_image` for a smooth transition from loading to game play.
10:
id: goal
doc: |
Every world contains exactly one goal zone. Solving this zone wins
the game.
11:
id: town
doc: |
This is the entry zone where the hero arrives after leaving the
swamp planet. Each planet can only have one town zone.
13:
id: win
doc: |
Shown when a game is won. The score is rendered above the tiles at
coordinates 5x7 and 6x7.
14:
id: lose
doc: |
Shown when a game is lost.
15:
id: trade
doc: |
In order to solve this zone and gain a new item the hero has to
trade something in.
16:
id: use
doc: |
This type of zone can be solved by making applying a tool or using
a keycard.
17:
id: find
doc: |
This type of zone can be solved without using items.
18:
id: find_unique_weapon
doc: |
This zone provides the hero with a unique weapon and will be
placed closed to a town zone.
zone_spot:
seq:
- id: column
doc: from bottom to top, 0xFFFF indicates empty tiles
type: u2
repeat: expr
repeat-expr: 3
hotspot:
doc: |
In addition to actions some puzzles and events are triggered by
hotspots. These hotspots are triggered when the hero steps on them or
places an item at the location. Additionally, hotspots are used during
world generation to mark places where NPCs can spawn.
seq:
- id: type
type: u4
enum: hotspot_type
- id: x
type: u2
- id: y
type: u2
- id: enabled
doc: |
If disabled, hotspots can not be triggered. See instruction opcodes
called `enable_hotspot` and `disable_hotspot`.
type: u2
- id: argument
type: u2
enums:
hotspot_type:
0:
id: drop_quest_item
doc: |
Drops the item provided by the zone when solved. Can be set to a
specific item, or to `0xFFFF` to use the one from the currently
assigned puzzle.
1:
id: spawn_location
doc: |
Possible spawn location for one of the zone's NPCs.
2:
id: drop_unique_weapon
doc: |
Hotspot that drops the unique weapon found in zones of type
`find_unique_weapon`.
3:
id: vehicle_to
doc: |
Used in `travel_start` zones as a trigger to teleport to the
corresponding `travel_end` zone. The hotspot argument contains the
id of the zone to teleport to.
4:
id: vehicle_back
doc: |
Counter part to `vehicle_to` hotspots. This is used to determine
the hero's position on the zone after the `vehicle_to` hotspot has
been triggered and to teleport back to the zone on main land.
5:
id: drop_map
doc: |
Hotspot that drops the map (aka locator) tile. One `find` zone
with a hotspot of this type will be placed next to a town during
world generation.
6:
id: drop_item
doc: |
Hotspot that, when triggered drops the item specified in the
hotspot's argument. If the item is set to `0xFFFF` the zone's
quest item will be dropped.
7:
id: npc
doc: |
This seems to be a placeholder for a pre-assigned NPC.
8:
id: drop_weapon
doc: |
Drops a weapon (specified by the hotspot argument) when triggered.
9:
id: door_in
doc: |
When triggered this hotspot type move the hero to the zone
specified in the hotspot argument. The hero's location on the new
zone will be determined by a corresponding `door_out` hotspot in
the target zone.
10:
id: door_out
doc: |
Determines where the hero will be placed when the zone is entered
through a door. When triggered, this transports the player back to
the `door_in` hotspot they game from.
11: unused
12: lock
13:
id: teleporter
doc: |
Teleporter hotspots can be used to instantly teleport to other
(visited) teleporters on the map
14:
id: ship_to_planet
doc: |
Behaves similar to the `vehicle_to` hotspot type but travels
between the town and the swamp planet.
15:
id: ship_from_planet
doc: |
Behaves similar to the `vehicle_back` hotspot type but travels
between the town and the swamp planet.
zone_auxiliary:
seq:
- id: marker
contents: "IZAX"
- id: size
type: u4
- type: u2
- id: num_monsters
type: u2
- id: monsters
type: monster
repeat: expr
repeat-expr: num_monsters
- id: num_required_items
type: u2
- id: required_items
doc: List of items that can be used to solve the zone.
type: u2
repeat: expr
repeat-expr: num_required_items
zone_auxiliary_2:
seq:
- id: marker
contents: "IZX2"
- id: size
type: u4
- id: num_provided_items
type: u2
- id: provided_items
doc: Items that can be gained when the zone is solved.
type: u2
repeat: expr
repeat-expr: num_provided_items
zone_auxiliary_3:
seq:
- id: marker
contents: "IZX3"
- id: size
type: u4
- id: num_npcs
type: u2
- id: npcs
doc: |
NPCs that can be placed in the zone to trade items with the hero.
type: u2
repeat: expr
repeat-expr: num_npcs
zone_auxiliary_4:
seq:
- id: marker
contents: "IZX4"
- id: size
type: u4
- type: u2
zones:
seq:
- id: num_zones
type: u2
- id: zones
type: zone
repeat: expr
repeat-expr: num_zones
puzzles:
seq:
- id: puzzles
type: puzzle
repeat: until
repeat-until: _.index == 0xFF_FF
puzzle:
seq:
- id: index
type: u2
- id: marker
if: index != 0xFF_FF
contents: "IPUZ"
- id: size
type: u4
if: index != 0xFF_FF
- id: item1_class
type: u4
enum: puzzle_item_class
if: index != 0xFF_FF
- id: item2_class
type: u4
enum: puzzle_item_class
if: index != 0xFF_FF
- type: u2
if: index != 0xFF_FF
- id: strings
type: prefixed_str
repeat: expr
repeat-expr: 5
if: index != 0xFF_FF
- id: item_1
type: u2
if: index != 0xFF_FF
enums:
puzzle_item_class:
0: keycard
1: tool
2: part
4: valuable
0xFFFF_FFFF: none
endf:
seq: []
tgen:
doc: |
The TGEN section is only present in non-english versions of the game. It's purpose or
internal structure is unknown.
seq:
- id: data
size: _parent.size
characters:
seq:
- id: characters
type: character
repeat: until
repeat-until: _.index == 0xFF_FF
character:
seq:
- id: index
type: u2
- id: marker
contents: "ICHA"
if: index != 0xFF_FF
- id: size
type: u4
if: index != 0xFF_FF
- id: name
type: strz
size: 16
if: index != 0xFF_FF
- id: type
type: u2
enum: character_type
if: index != 0xFF_FF
- id: movement_type
type: u2
enum: movement_type
if: index != 0xFF_FF
- id: frame_1
type: char_frame
if: index != 0xFF_FF
- id: frame_2
type: char_frame
if: index != 0xFF_FF
- id: frame_3
type: char_frame
if: index != 0xFF_FF
enums:
character_type:
1: hero
2: enemy
4: weapon
movement_type:
0: none
4: sit
9: wander
10: patrol
12: animation
char_frame:
seq:
- id: tiles
type: u2
repeat: expr
repeat-expr: 0x8
character_auxiliaries:
seq:
- id: auxiliaries
type: character_auxiliary
repeat: until
repeat-until: _.index == 0xFF_FF
character_auxiliary:
seq:
- id: index
type: u2
- id: damage
type: s2
if: index != 0xFF_FF
character_weapons:
seq:
- id: weapons
type: character_weapon
repeat: until
repeat-until: _.index == 0xFF_FF
character_weapon:
seq:
- id: index
type: u2
- id: reference
doc: |
If the character referenced by index is a monster, this is a
reference to their weapon, otherwise this is the index of the
weapon's sound
type: u2
if: index != 0xFF_FF
- id: health
type: u2
if: index != 0xFF_FF
action_names:
seq:
- id: names
type: zone_action_name
repeat: until
repeat-until: _.zone_id == 0xFF_FF
zone_action_name:
seq:
- id: zone_id
type: u2
- id: action_names
type: action_name
repeat: until
repeat-until: _.action_id == 0xFF_FF
if: zone_id != 0xFF_FF
action_name:
seq:
- id: action_id
type: u2
- id: name
type: strz
size: 0x10
if: action_id != 0xFF_FF
puzzle_names:
seq:
- id: num_puzzle_names
type: u2
- id: puzzle_names
type: strz
size: 0x10
repeat: expr
repeat-expr: num_puzzle_names
zone_names:
seq:
- id: zone_names
type: zone_name
repeat: until
repeat-until: _.zone_id == 0xFF_FF
zone_name:
seq:
- id: zone_id
type: u2
- id: name
type: strz
size: 0x10
if: zone_id != 0xFF_FF
hotspots:
seq:
- id: zone_hotspots
type: zone_hotspot
repeat: until
repeat-until: _.zone_id == 0xFF_FF
zone_hotspot:
seq:
- id: zone_id
type: u2
- id: num_hotspots
type: u2
if: zone_id != 0xFF_FF
- id: hotspots
type: hotspot
repeat: expr
repeat-expr: num_hotspots
if: zone_id != 0xFF_FF
actions:
seq:
- id: zone_actions
type: zone_action
repeat: until
repeat-until: _.zone_id == 0xFF_FF
zone_action:
seq:
- id: zone_id
type: u2
- id: num_actions
type: u2
if: zone_id != 0xFF_FF
- id: actions
type: action
repeat: expr
repeat-expr: num_actions
if: zone_id != 0xFF_FF
zones_aux_1:
seq:
- id: zone_auxiliaries
type: zone_auxiliary
repeat: expr
repeat-expr: _root.catalog[4].content.as<zones>.num_zones
zones_aux_2:
seq:
- id: zone_auxiliaries
type: zone_auxiliary_2
repeat: expr
repeat-expr: _root.catalog[4].content.as<zones>.num_zones
zones_aux_3:
seq:
- id: zone_auxiliaries
type: zone_auxiliary_3
repeat: expr
repeat-expr: _root.catalog[4].content.as<zones>.num_zones
zones_aux_4:
seq:
- id: zone_auxiliaries
type: zone_auxiliary_4
repeat: expr
repeat-expr: _root.catalog[4].content.as<zones>.num_zones
# Utilities
prefixed_str:
seq:
- id: len_content
type: u2
- id: content
type: str
size: len_content
prefixed_strz:
seq:
- id: len_content
type: u2
- id: content
type: strz
size: len_content
Yodasav.ksy
This is a machine-readable definition of the save game format used by Yoda Stories. It can be used to generate a parser or inspect files online in the Kaitai Web IDE.
meta:
id: yodasav
file-extension: wld
application: "Yoda Stories"
endian: le
encoding: ASCII
seq:
- id: magic
contents: "YODASAV44"
- id: seed
type: u4
- id: planet
type: u4
- id: on_dagobah
type: u4
- id: puzzles1
type: id_array
- id: puzzles2
type: id_array
- id: dagobah
type: dagobah
- id: world
type: world
- id: inventory_count
type: u4
- id: inventory
type: u2
repeat: expr
repeat-expr: inventory_count
- id: current_zone
type: u2
- id: world_x
type: u4
- id: world_y
type: u4
- id: current_weapon
type: s2
- id: current_ammo
type: s2
if: current_weapon != -1
- id: force_ammo
type: s2
- id: blaster_ammo
type: s2
- id: blaster_rifle_ammo
type: s2
- id: zone_x
type: u4
- id: zone_y
type: u4
- id: damage_taken
type: u4
- id: lives_left
type: u4
- id: difficulty
type: u4
- id: time_elapsed
type: u4
- id: world_size
type: u2
- id: unknown_array_count
type: u2
- id: unknown_array_sum
type: u2
- id: end_puzzle
type: u4
- id: end_puzzle_again
type: u4
types:
id_array:
seq:
- id: count
type: u2
- id: content
type: u2
repeat: expr
repeat-expr: count
world_thing:
seq:
- id: unknown1
type: u4
- id: unknown2
type: u4
- id: unknown3
type: u4
- id: unknown4
type: u4
- id: unknown5
type: u4
- id: zone_id
type: u2
- id: unknown6
type: u2
- id: required_item
type: u2
- id: provided_item
type: u2
- id: unknown7
type: u2
- id: additionally_required_item
type: u2
- id: unknown8
type: u2
- id: puzzle_npc
type: u2
- id: unknown9
type: u4
- id: unknown10
type: u2
- id: rooms
type: room
dagobah:
seq:
- id: world_things
type: world_thing
repeat: expr
repeat-expr: 2 * 2
- id: zones
type: zone
repeat: until
repeat-until: _.unknown1 == -1 or _.unknown2 == -1
world:
seq:
- id: world_things
type: world_thing
repeat: expr
repeat-expr: 10 * 10
- id: zones
type: zone
repeat: until
repeat-until: _.unknown1 == -1 or _.unknown2 == -1
rooms:
seq:
- id: rooms
type: room
repeat: until
repeat-until: _.unknown1 == -1
room:
seq:
- id: unknown1
type: s4
- id: unknown2
type: s4
- id: zone_id
type: s2
if: unknown1 == -1
- id: unknown3
type: u4
if: unknown1 == -1
zone:
seq:
- id: unknown1
type: s4
- id: unknown2
type: s4
List of game files
The following is a list of checksum of files related to Yoda Stories or Indiana Jones and His Desktop Adventures. If you have access to other versions of the games feel free to add them below.
sha1 | Common Name | Description |
---|---|---|
a8e18864184d49feaf0b74b93f60855f40ffe9bf | yopatch6.exe | Installer for Yoda Stories update |
437e9ebdfdfe7511c94afb6eebaf2c367cbec33a | Yodesk.dta | Update game file provided by yopatch6 |
c862c5cc94b5d57b4e296f5f4e2b4508fcb51d6a | indy.pal | Color palette used by Indy |
6472ed051d2046e01f4ba44b19a443615c75979e | yoda.pal | Yoda Stories color palette used by Yoda Stories (256 colors at 4byte per color) |
cf328158f596278b9b30aa0cd9dfe91cac062d92 | disk1.img | Indy, Spanish, 3.5" floppy, see https://www.goodolddays.net/diskimages/id%2C2819/ |
0b43a75a09180e68629833d305c50ace6493bf93 | disk1.img | Indy, French, 3.5" floppy, see https://www.goodolddays.net/diskimages/id%2C2819/ |
f12f8a2ab25a89e26e25457dd7332cdf4135ba7a | disk1.img | Indy, English, 3.5" floppy, see https://www.goodolddays.net/diskimages/id%2C2819/ |
00d5755679a750f574bd9b0c2f8d970e5333e0d1 | YODA_GERMAN.iso | ISO 9660 CD-ROM filesystem data 'YODA_GERMAN' |
0d8f15b7920140c82619cf0badc09a9e59924c1e | YODA_SPANISH.iso | ISO 9660 CD-ROM filesystem data 'YODASPANISH |
a0efe4819c9c7325437842f2d1b7ec5082cbc0c6 | Indydesk.exe | Indy patch file posted 10/96 |
b816ee3a9fccd68a70801ec4ff5fe9dbd8c2bf64 | YodaDemo.exe | Self-extracting archive of Yoda Stories Demo |
24931dc214824d525a084ad0073b3211235c2f60 | Indyprev.zip | Indiana Jones and His Desktop Adventures Demo |
Yoda Stories
Yoda Stories (English)
sha1 | Common Name |
---|---|
6256e9cc90f227163ef54f69e57733a45df35982 | ./BITMAPS/PYODAY.BMP |
b64a263acbd24612e66e46ce2a2e151c3812cb23 | ./BITMAPS/SCREEN.BMP |
5cb7b9ec4fdadf8d88fda6d266de584e083ea80a | ./BITMAPS/IYODAY.BMP |
dc399eee158bb89813d76aa16ca65473f70588fb | ./BITMAPS/LMMY.BMP |
c6b1c2341507160d0bf055bdaa7243a33636390e | ./BITMAPS/LMMB.BMP |
1394fec8991a0bf2ba01c793fd7ff6635f61c217 | ./BITMAPS/IYODAB.BMP |
33203c1c173d4da372bf3424b9b2e08e9c0bf6a1 | ./BITMAPS/PYODAB.BMP |
b6f27160b8b560891af2f617fc761262077a1e7d | ./REGISTER ON-LINE.URL |
50ef08a3e02edc2954e7494911261d85d52c0506 | ./INSTALL/INST32I.EX |
d3a39cc6532dec55b843af8efdfce0c6f7176e22 | ./INSTALL/SETUP.EXE |
d894923d28ab6154a2b795fcc0f73c1e42d0262c | ./INSTALL/SETUP.INS |
77f9873ebcd25400d4825101c255b5a1ce7c1106 | ./INSTALL/SETUP.INI |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.INI |
e7ec0b86b1efbed2515942dcc3332159eb7d0bf5 | ./INSTALL/WEBSITE.EXE |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.GID |
140bee85e817a79d5ccc1d1e8e1d66199e41ffbe | ./INSTALL/_SETUP.DLL |
b19e2e4f93b336042a1eddae12ea2e653834a7a3 | ./INSTALL/_SETUP.LIB |
fe96bd82d167f50cb8cd9c9a32d72b77f45f8002 | ./INSTALL/_ISDEL.EXE |
cf63696315314488557fbecac937908e5e8c7288 | ./INSTALL/REGISTER.EXE |
a955c3839ec956d9eb04d3e78cac4bc1c028ec1f | ./YODESK.EXE |
0372868bf5ac8040a9d3bba7a0bed9241e2308d2 | ./VISIT WWW.LUCASARTS.COM.URL |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./SFX/HURT.WAV |
52c2476718520cc52b47e8e1966f803e888bdf0a | ./SFX/GRENADE.WAV |
85314d0afd63b32c5cd9810f7a43a05e293d2247 | ./SFX/CHESTLRG.WAV |
d5e3f378b894a8ee179e2a2d7e17eb86d9c267bd | ./SFX/BUZZMED.WAV |
31d60649b6797626e38421b32a27eac6a9c84df6 | ./SFX/MYSTERY.WAV |
8a397e81ea87985ebe0244414ab21ad47d7228f9 | ./SFX/WALKER.WAV |
d5b4c7eec94b3c88f33f792db74b539829ef21e3 | ./SFX/CANTINA.WAV |
200886036f2af0e382e9b3986542e35662f99929 | ./SFX/LOCATOR.WAV |
b0ada8bbd7c352a2b489faa9fdb640abc8cd220a | ./SFX/PISTOL.WAV |
4e64a3a79a879c91c35bf614e5b81965ecf434eb | ./SFX/BUZZLOW.WAV |
7c45cbecd946fee69b515bb01c436bd82acc0d14 | ./SFX/EMPTHEME.WAV |
e8e40ba4bd82630434b826a3265edc8549ae34b3 | ./SFX/WOOKIE.WAV |
7791b4cad2437e10169c1f60d47a0fae953f167a | ./SFX/ARMFORCE.WAV |
40e6664e59ed24e7107d5785e6bf72375546e576 | ./SFX/BLASTER.WAV |
1d301d467868f8727e7327a81e6dc0a4ac4d7a9c | ./SFX/DOORELEC.WAV |
72d23409767760589c08e52495ab4136e5af1ee6 | ./SFX/SABEROUT.WAV |
ef059f05dcb04d32f0af1fbd7163b962e6e4fd0d | ./SFX/RIFLE.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-7.WAV |
5c8c54eb51f19cdb0e3745e30cf5d9dccdb25151 | ./SFX/SWITCH-6.WAV |
caa7ad2b6e00e02ebb8f136c33d372a0bb7d8b1c | ./SFX/VADER.WAV |
071bd82aff663e50aa78e8d3fe2001f6aab1f7d8 | ./SFX/EEP.WAV |
978cebdf7023a24acd2b0e0795c034da1c9e47b3 | ./SFX/BANGHUGE.WAV |
717b92788485092181957614fd3b156f4549b51c | ./SFX/SWITCH-4.WAV |
3191a59954f98347c55be705c27064d1c96ce825 | ./SFX/SWITCH-5.WAV |
9bd9dbe0bac4fe541c620bac501cfbaf179a29ce | ./SFX/TRUCKIN.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-1.WAV |
e0ab059defcc74c0f44c246750f442203930471a | ./SFX/SPEEDER.WAV |
8e9962d0069c0b74c07ce61005bf9dc3003b9f9c | ./SFX/BANGLRG.WAV |
55ebccfc7ea4327ffda2607e081c4d99fcccdc5d | ./SFX/HUGEDOOR.WAV |
7af931273d6374af73538b1580ff04f287de6ded | ./SFX/SCHWING.WAV |
1b4293242d61461914623ffad36867537ab199d5 | ./SFX/TRANSPRT.WAV |
7995af7e4cd2b97e5419e1ea93dfcb5eb7c356c8 | ./SFX/TRYAGAIN.WAV |
5f384cd6565305544f06f650a64b01f4f15c4bbb | ./SFX/SWITCH-2.WAV |
690c39b1ea1cdf86e28cf1335cb620c3ba92727a | ./SFX/YOUWIN.WAV |
97269a0f50b7bf37530d4c0b7ec0ce9089c8718d | ./SFX/FORCE.WAV |
5687e94a1faac7dbe75881e9dd6c1c8fe031984d | ./SFX/ARMED.WAV |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SFX/SHPOONK.WAV |
dd9ce24759ac8ddf5e09f6b848c5dd71cd9a1b6c | ./SFX/SWITCH-3.WAV |
3d0f7ad1aa43aa7d2e8daf3c509d307185fd252e | ./SFX/R2D2-2.WAV |
d55ff1a47a2a1a08c26990a713e2310546461703 | ./SFX/BONG.WAV |
d7e352947ee21ef48b1f020c42c999820caa176d | ./SFX/R2D2-1.WAV |
bdc3addce338d60d2b4e4fe3452508fcfdd0f7a4 | ./SFX/SABER.WAV |
3fb938e254ba8b9426b38857d02de48c998db9a2 | ./SFX/XWINGIN.WAV |
9e2f78a639a27685f9184eef514af521d3f9223b | ./SFX/BLEEPSML.WAV |
9920d7446a2f259f0a62dffd0e61e30fb7eb4dfd | ./SFX/BUZZHIGH.WAV |
5b5e4581d77527afc79163fdcc31f0b4ded65005 | ./SFX/CHESTSML.WAV |
b710cd2f427f742ee1202adf04d9caf242ea6026 | ./SFX/SWITCH-8.WAV |
3f2d782c4788ae1bfeed65103863c274d9978649 | ./SFX/TIEBY.WAV |
833757378d9e8ad02c0a441439349402c627328d | ./SFX/IMPBLST.WAV |
419cc1734f33953219b94d9316f2780a1655aa7d | ./SFX/BLIP.WAV |
b55808ae16478322f62b3a510b5618addca12cfc | ./SFX/SABERSWG.WAV |
c7bde605481cc7450397fc966d2edcf949eddaf2 | ./SFX/XWINGOUT.WAV |
3f8f63d62dababaed9c9fd0da3c5687fc8d6d91c | ./SFX/TRUCKOUT.WAV |
79a9a56abd0525f2e2980009a8ae313cd91f382c | ./SFX/FLOURISH.WAV |
2722f7599fe8ac7e4d3876276aea3c71fdd53327 | ./SFX/CHIRP.WAV |
75b1ebef0a2b29f14d787fe6ca8af3d2fc15af5b | ./SFX/OPENING.WAV |
37e222b09f2b1cf86dfbbac5cd06ce1d7bb79c11 | ./SFX/SPLASH.WAV |
2d4d0af951307083b7cce9840e7ee4d3013d2590 | ./SFX/RIFLBLST.WAV |
ccbe0e1d23f353e2ff5f8a50a41cbf3e1b62285a | ./SFX/MAPCLS.WAV |
65f50467bd6331d13498d547c9d08dc00b2ebcca | ./SFX/XWINGBY.WAV |
7640aefae2ec587bfeeb3456a66fa57e6d3b6d06 | ./SFX/CRASH.WAV |
ebddf621f032f619d14b3b4eae2296fe58413efa | ./SFX/BANGMED.WAV |
e8febb3a41d4eef2587dad9cd5e2719d7392635d | ./SFX/PUSH.WAV |
cd5db260b3b0879e48064c65eee061942f955ced | ./SFX/NOGO.WAV |
5e7bc1330365191feecd53d8595ee1da96b74b85 | ./SFX/MOVEROCK.WAV |
b1e5be033b13b24806ea961f7998fdffe2f81803 | ./SFX/DOORPNUM.WAV |
184b008cd9a7d78b62959ad66f16a03d27688208 | ./YODESK.CNT |
13e914ad378bcef9a7b030200e0dc7a66c078473 | ./WAVEMIX.INI |
66c502f8373a149bd310f364f4d4d29cf61dad06 | ./YODESK.GID |
b6d1ac4d9f165403898531341d13885c770d4177 | ./MSVCRT40.DLL |
9fa85e8177d2df436564c97775845b9ab27b9b94 | ./YODESK.HLP |
21265b5d3d600ecd9869a88c70096b3e0ea3c6b2 | ./WAVMIX32.DLL |
437e9ebdfdfe7511c94afb6eebaf2c367cbec33a | ./YODESK.DTA |
Yoda Stories (Spanish)
sha1 | Common Name |
---|---|
77f5799c10da7afde51e6166a2c27d66f8b609f9 | ./BITMAPS/PYODAY.BMP |
2f8327c3b2000f44cd17ef7fd2ba59815f1d1262 | ./BITMAPS/SCREEN.BMP |
ee1c8b63e686a96c22c91913e372ae4df9e6e6b2 | ./BITMAPS/IYODAY.BMP |
4e588386f0d41df3fb1bf3a9a0ab49a4cd6b516a | ./BITMAPS/LMMY.BMP |
f4ab98bbbe7254c7bcaff7413c12897a0a1669d6 | ./BITMAPS/LMMB.BMP |
fe59382fbc7cb948c23ddfc78ad1ec4985c8e587 | ./BITMAPS/IYODAB.BMP |
4201ef8de520493f311d1b7f06a3ac0aaa80a710 | ./BITMAPS/PYODAB.BMP |
50ef08a3e02edc2954e7494911261d85d52c0506 | ./INSTALL/INST32I.EX |
d3a39cc6532dec55b843af8efdfce0c6f7176e22 | ./INSTALL/SETUP.EXE |
a148e180e70939a721449551297ee4cc47b0620b | ./INSTALL/SETUP.INS |
77f9873ebcd25400d4825101c255b5a1ce7c1106 | ./INSTALL/SETUP.INI |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.INI |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.GID |
0e45ae0b619b6d2924eed33b4dc5480e12a7c6fe | ./INSTALL/_SETUP.DLL |
03f70a3e1bd3bdd5f908ac3aad464fd87fb33eb2 | ./INSTALL/_SETUP.LIB |
fe96bd82d167f50cb8cd9c9a32d72b77f45f8002 | ./INSTALL/_ISDEL.EXE |
6c0c0934b026ccd2c40916241fbd991c95d6487f | ./YODESK.EXE |
0372868bf5ac8040a9d3bba7a0bed9241e2308d2 | ./VISITA WWW.LUCASARTS.COM.URL |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./SFX/HURT.WAV |
52c2476718520cc52b47e8e1966f803e888bdf0a | ./SFX/GRENADE.WAV |
85314d0afd63b32c5cd9810f7a43a05e293d2247 | ./SFX/CHESTLRG.WAV |
d5e3f378b894a8ee179e2a2d7e17eb86d9c267bd | ./SFX/BUZZMED.WAV |
31d60649b6797626e38421b32a27eac6a9c84df6 | ./SFX/MYSTERY.WAV |
8a397e81ea87985ebe0244414ab21ad47d7228f9 | ./SFX/WALKER.WAV |
d5b4c7eec94b3c88f33f792db74b539829ef21e3 | ./SFX/CANTINA.WAV |
200886036f2af0e382e9b3986542e35662f99929 | ./SFX/LOCATOR.WAV |
b0ada8bbd7c352a2b489faa9fdb640abc8cd220a | ./SFX/PISTOL.WAV |
4e64a3a79a879c91c35bf614e5b81965ecf434eb | ./SFX/BUZZLOW.WAV |
7c45cbecd946fee69b515bb01c436bd82acc0d14 | ./SFX/EMPTHEME.WAV |
e8e40ba4bd82630434b826a3265edc8549ae34b3 | ./SFX/WOOKIE.WAV |
7791b4cad2437e10169c1f60d47a0fae953f167a | ./SFX/ARMFORCE.WAV |
40e6664e59ed24e7107d5785e6bf72375546e576 | ./SFX/BLASTER.WAV |
1d301d467868f8727e7327a81e6dc0a4ac4d7a9c | ./SFX/DOORELEC.WAV |
72d23409767760589c08e52495ab4136e5af1ee6 | ./SFX/SABEROUT.WAV |
ef059f05dcb04d32f0af1fbd7163b962e6e4fd0d | ./SFX/RIFLE.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-7.WAV |
5c8c54eb51f19cdb0e3745e30cf5d9dccdb25151 | ./SFX/SWITCH-6.WAV |
caa7ad2b6e00e02ebb8f136c33d372a0bb7d8b1c | ./SFX/VADER.WAV |
071bd82aff663e50aa78e8d3fe2001f6aab1f7d8 | ./SFX/EEP.WAV |
978cebdf7023a24acd2b0e0795c034da1c9e47b3 | ./SFX/BANGHUGE.WAV |
717b92788485092181957614fd3b156f4549b51c | ./SFX/SWITCH-4.WAV |
3191a59954f98347c55be705c27064d1c96ce825 | ./SFX/SWITCH-5.WAV |
9bd9dbe0bac4fe541c620bac501cfbaf179a29ce | ./SFX/TRUCKIN.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-1.WAV |
e0ab059defcc74c0f44c246750f442203930471a | ./SFX/SPEEDER.WAV |
8e9962d0069c0b74c07ce61005bf9dc3003b9f9c | ./SFX/BANGLRG.WAV |
55ebccfc7ea4327ffda2607e081c4d99fcccdc5d | ./SFX/HUGEDOOR.WAV |
7af931273d6374af73538b1580ff04f287de6ded | ./SFX/SCHWING.WAV |
1b4293242d61461914623ffad36867537ab199d5 | ./SFX/TRANSPRT.WAV |
7995af7e4cd2b97e5419e1ea93dfcb5eb7c356c8 | ./SFX/TRYAGAIN.WAV |
5f384cd6565305544f06f650a64b01f4f15c4bbb | ./SFX/SWITCH-2.WAV |
690c39b1ea1cdf86e28cf1335cb620c3ba92727a | ./SFX/YOUWIN.WAV |
97269a0f50b7bf37530d4c0b7ec0ce9089c8718d | ./SFX/FORCE.WAV |
5687e94a1faac7dbe75881e9dd6c1c8fe031984d | ./SFX/ARMED.WAV |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SFX/SHPOONK.WAV |
dd9ce24759ac8ddf5e09f6b848c5dd71cd9a1b6c | ./SFX/SWITCH-3.WAV |
3d0f7ad1aa43aa7d2e8daf3c509d307185fd252e | ./SFX/R2D2-2.WAV |
d55ff1a47a2a1a08c26990a713e2310546461703 | ./SFX/BONG.WAV |
d7e352947ee21ef48b1f020c42c999820caa176d | ./SFX/R2D2-1.WAV |
bdc3addce338d60d2b4e4fe3452508fcfdd0f7a4 | ./SFX/SABER.WAV |
3fb938e254ba8b9426b38857d02de48c998db9a2 | ./SFX/XWINGIN.WAV |
9e2f78a639a27685f9184eef514af521d3f9223b | ./SFX/BLEEPSML.WAV |
9920d7446a2f259f0a62dffd0e61e30fb7eb4dfd | ./SFX/BUZZHIGH.WAV |
5b5e4581d77527afc79163fdcc31f0b4ded65005 | ./SFX/CHESTSML.WAV |
b710cd2f427f742ee1202adf04d9caf242ea6026 | ./SFX/SWITCH-8.WAV |
3f2d782c4788ae1bfeed65103863c274d9978649 | ./SFX/TIEBY.WAV |
833757378d9e8ad02c0a441439349402c627328d | ./SFX/IMPBLST.WAV |
419cc1734f33953219b94d9316f2780a1655aa7d | ./SFX/BLIP.WAV |
b55808ae16478322f62b3a510b5618addca12cfc | ./SFX/SABERSWG.WAV |
c7bde605481cc7450397fc966d2edcf949eddaf2 | ./SFX/XWINGOUT.WAV |
3f8f63d62dababaed9c9fd0da3c5687fc8d6d91c | ./SFX/TRUCKOUT.WAV |
79a9a56abd0525f2e2980009a8ae313cd91f382c | ./SFX/FLOURISH.WAV |
2722f7599fe8ac7e4d3876276aea3c71fdd53327 | ./SFX/CHIRP.WAV |
75b1ebef0a2b29f14d787fe6ca8af3d2fc15af5b | ./SFX/OPENING.WAV |
37e222b09f2b1cf86dfbbac5cd06ce1d7bb79c11 | ./SFX/SPLASH.WAV |
2d4d0af951307083b7cce9840e7ee4d3013d2590 | ./SFX/RIFLBLST.WAV |
ccbe0e1d23f353e2ff5f8a50a41cbf3e1b62285a | ./SFX/MAPCLS.WAV |
65f50467bd6331d13498d547c9d08dc00b2ebcca | ./SFX/XWINGBY.WAV |
7640aefae2ec587bfeeb3456a66fa57e6d3b6d06 | ./SFX/CRASH.WAV |
ebddf621f032f619d14b3b4eae2296fe58413efa | ./SFX/BANGMED.WAV |
e8febb3a41d4eef2587dad9cd5e2719d7392635d | ./SFX/PUSH.WAV |
cd5db260b3b0879e48064c65eee061942f955ced | ./SFX/NOGO.WAV |
5e7bc1330365191feecd53d8595ee1da96b74b85 | ./SFX/MOVEROCK.WAV |
b1e5be033b13b24806ea961f7998fdffe2f81803 | ./SFX/DOORPNUM.WAV |
8bbefddff0da779d9843300544080d02a8364032 | ./YODESK.CNT |
13e914ad378bcef9a7b030200e0dc7a66c078473 | ./WAVEMIX.INI |
b6d1ac4d9f165403898531341d13885c770d4177 | ./MSVCRT40.DLL |
4d4e45a459cfbe560be779ab2195185f8c2165b7 | ./YODESK.HLP |
21265b5d3d600ecd9869a88c70096b3e0ea3c6b2 | ./WAVMIX32.DLL |
2650cf79560305cee94f677bc0f2acd692a853f6 | ./YODESK.DTA |
Yoda Stories (German)
sha1 | Common Name |
---|---|
37ebcdff84f564ba57c2dbdab24f68e4b4aca162 | ./BITMAPS/PYODAY.BMP |
9274750d5c92c3a6e38f594a215305a121130db9 | ./BITMAPS/SCREEN.BMP |
59b9f394688eac325ca763102fda4a62abccc4dc | ./BITMAPS/IYODAY.BMP |
139ac3cafdd99f60364fc1305dca90d1b4956f9f | ./BITMAPS/LMMY.BMP |
f39956775f34f5bf0999d84597b57e2858ce1598 | ./BITMAPS/LMMB.BMP |
a4decad5295523f21bf8a4e4212e1ef7441bc80b | ./BITMAPS/IYODAB.BMP |
d0960ad5a3822659b11426a806fdcfdc15fd985a | ./BITMAPS/PYODAB.BMP |
50ef08a3e02edc2954e7494911261d85d52c0506 | ./INSTALL/INST32I.EX |
d3a39cc6532dec55b843af8efdfce0c6f7176e22 | ./INSTALL/SETUP.EXE |
597dd13d90517ca5056c0389072110db6874dd46 | ./INSTALL/SETUP.INS |
77f9873ebcd25400d4825101c255b5a1ce7c1106 | ./INSTALL/SETUP.INI |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.INI |
da39a3ee5e6b4b0d3255bfef95601890afd80709 | ./INSTALL/YODESK.GID |
ed96ae8387da5ffcb3b92ed091ae2ea42eb0d74b | ./INSTALL/_SETUP.DLL |
daf49fac20ee018c1799bdf711ca3a576888ed64 | ./INSTALL/_SETUP.LIB |
fe96bd82d167f50cb8cd9c9a32d72b77f45f8002 | ./INSTALL/_ISDEL.EXE |
835ebc3c25b963d025658845a72126ae362653bb | ./YODESK.EXE |
0372868bf5ac8040a9d3bba7a0bed9241e2308d2 | ./VISIT WWW.LUCASARTS.COM.URL |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./SFX/HURT.WAV |
52c2476718520cc52b47e8e1966f803e888bdf0a | ./SFX/GRENADE.WAV |
85314d0afd63b32c5cd9810f7a43a05e293d2247 | ./SFX/CHESTLRG.WAV |
d5e3f378b894a8ee179e2a2d7e17eb86d9c267bd | ./SFX/BUZZMED.WAV |
31d60649b6797626e38421b32a27eac6a9c84df6 | ./SFX/MYSTERY.WAV |
8a397e81ea87985ebe0244414ab21ad47d7228f9 | ./SFX/WALKER.WAV |
d5b4c7eec94b3c88f33f792db74b539829ef21e3 | ./SFX/CANTINA.WAV |
200886036f2af0e382e9b3986542e35662f99929 | ./SFX/LOCATOR.WAV |
b0ada8bbd7c352a2b489faa9fdb640abc8cd220a | ./SFX/PISTOL.WAV |
4e64a3a79a879c91c35bf614e5b81965ecf434eb | ./SFX/BUZZLOW.WAV |
7c45cbecd946fee69b515bb01c436bd82acc0d14 | ./SFX/EMPTHEME.WAV |
e8e40ba4bd82630434b826a3265edc8549ae34b3 | ./SFX/WOOKIE.WAV |
7791b4cad2437e10169c1f60d47a0fae953f167a | ./SFX/ARMFORCE.WAV |
40e6664e59ed24e7107d5785e6bf72375546e576 | ./SFX/BLASTER.WAV |
1d301d467868f8727e7327a81e6dc0a4ac4d7a9c | ./SFX/DOORELEC.WAV |
72d23409767760589c08e52495ab4136e5af1ee6 | ./SFX/SABEROUT.WAV |
ef059f05dcb04d32f0af1fbd7163b962e6e4fd0d | ./SFX/RIFLE.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-7.WAV |
5c8c54eb51f19cdb0e3745e30cf5d9dccdb25151 | ./SFX/SWITCH-6.WAV |
caa7ad2b6e00e02ebb8f136c33d372a0bb7d8b1c | ./SFX/VADER.WAV |
071bd82aff663e50aa78e8d3fe2001f6aab1f7d8 | ./SFX/EEP.WAV |
978cebdf7023a24acd2b0e0795c034da1c9e47b3 | ./SFX/BANGHUGE.WAV |
717b92788485092181957614fd3b156f4549b51c | ./SFX/SWITCH-4.WAV |
3191a59954f98347c55be705c27064d1c96ce825 | ./SFX/SWITCH-5.WAV |
9bd9dbe0bac4fe541c620bac501cfbaf179a29ce | ./SFX/TRUCKIN.WAV |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./SFX/SWITCH-1.WAV |
e0ab059defcc74c0f44c246750f442203930471a | ./SFX/SPEEDER.WAV |
8e9962d0069c0b74c07ce61005bf9dc3003b9f9c | ./SFX/BANGLRG.WAV |
55ebccfc7ea4327ffda2607e081c4d99fcccdc5d | ./SFX/HUGEDOOR.WAV |
7af931273d6374af73538b1580ff04f287de6ded | ./SFX/SCHWING.WAV |
1b4293242d61461914623ffad36867537ab199d5 | ./SFX/TRANSPRT.WAV |
7995af7e4cd2b97e5419e1ea93dfcb5eb7c356c8 | ./SFX/TRYAGAIN.WAV |
5f384cd6565305544f06f650a64b01f4f15c4bbb | ./SFX/SWITCH-2.WAV |
690c39b1ea1cdf86e28cf1335cb620c3ba92727a | ./SFX/YOUWIN.WAV |
97269a0f50b7bf37530d4c0b7ec0ce9089c8718d | ./SFX/FORCE.WAV |
5687e94a1faac7dbe75881e9dd6c1c8fe031984d | ./SFX/ARMED.WAV |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SFX/SHPOONK.WAV |
dd9ce24759ac8ddf5e09f6b848c5dd71cd9a1b6c | ./SFX/SWITCH-3.WAV |
3d0f7ad1aa43aa7d2e8daf3c509d307185fd252e | ./SFX/R2D2-2.WAV |
d55ff1a47a2a1a08c26990a713e2310546461703 | ./SFX/BONG.WAV |
d7e352947ee21ef48b1f020c42c999820caa176d | ./SFX/R2D2-1.WAV |
bdc3addce338d60d2b4e4fe3452508fcfdd0f7a4 | ./SFX/SABER.WAV |
3fb938e254ba8b9426b38857d02de48c998db9a2 | ./SFX/XWINGIN.WAV |
9e2f78a639a27685f9184eef514af521d3f9223b | ./SFX/BLEEPSML.WAV |
9920d7446a2f259f0a62dffd0e61e30fb7eb4dfd | ./SFX/BUZZHIGH.WAV |
5b5e4581d77527afc79163fdcc31f0b4ded65005 | ./SFX/CHESTSML.WAV |
b710cd2f427f742ee1202adf04d9caf242ea6026 | ./SFX/SWITCH-8.WAV |
3f2d782c4788ae1bfeed65103863c274d9978649 | ./SFX/TIEBY.WAV |
833757378d9e8ad02c0a441439349402c627328d | ./SFX/IMPBLST.WAV |
419cc1734f33953219b94d9316f2780a1655aa7d | ./SFX/BLIP.WAV |
b55808ae16478322f62b3a510b5618addca12cfc | ./SFX/SABERSWG.WAV |
c7bde605481cc7450397fc966d2edcf949eddaf2 | ./SFX/XWINGOUT.WAV |
3f8f63d62dababaed9c9fd0da3c5687fc8d6d91c | ./SFX/TRUCKOUT.WAV |
79a9a56abd0525f2e2980009a8ae313cd91f382c | ./SFX/FLOURISH.WAV |
2722f7599fe8ac7e4d3876276aea3c71fdd53327 | ./SFX/CHIRP.WAV |
75b1ebef0a2b29f14d787fe6ca8af3d2fc15af5b | ./SFX/OPENING.WAV |
37e222b09f2b1cf86dfbbac5cd06ce1d7bb79c11 | ./SFX/SPLASH.WAV |
2d4d0af951307083b7cce9840e7ee4d3013d2590 | ./SFX/RIFLBLST.WAV |
ccbe0e1d23f353e2ff5f8a50a41cbf3e1b62285a | ./SFX/MAPCLS.WAV |
65f50467bd6331d13498d547c9d08dc00b2ebcca | ./SFX/XWINGBY.WAV |
7640aefae2ec587bfeeb3456a66fa57e6d3b6d06 | ./SFX/CRASH.WAV |
ebddf621f032f619d14b3b4eae2296fe58413efa | ./SFX/BANGMED.WAV |
e8febb3a41d4eef2587dad9cd5e2719d7392635d | ./SFX/PUSH.WAV |
cd5db260b3b0879e48064c65eee061942f955ced | ./SFX/NOGO.WAV |
5e7bc1330365191feecd53d8595ee1da96b74b85 | ./SFX/MOVEROCK.WAV |
b1e5be033b13b24806ea961f7998fdffe2f81803 | ./SFX/DOORPNUM.WAV |
6c22a68c21e6f5f1c1575fc070f14767e3759a58 | ./YODESK.CNT |
13e914ad378bcef9a7b030200e0dc7a66c078473 | ./WAVEMIX.INI |
b6d1ac4d9f165403898531341d13885c770d4177 | ./MSVCRT40.DLL |
64cf1eb8c83cc50f9f44ff3c3292a86b36768f9d | ./YODESK.HLP |
21265b5d3d600ecd9869a88c70096b3e0ea3c6b2 | ./WAVMIX32.DLL |
967ea881be2c7c5df9e5742722fe8e448592652f | ./yodesk.dta |
Yoda Stories Demo (English)
sha1 | Common Name |
---|---|
425b04cc5e1fd5d3da477a8314246baf161daffc | ./YodaDemo.hlp |
46734006c8e08faa15d2b2c2e32834ba9e3622ac | ./YodaDemo.dta |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./sfx/hurt.wav |
52c2476718520cc52b47e8e1966f803e888bdf0a | ./sfx/grenade.wav |
85314d0afd63b32c5cd9810f7a43a05e293d2247 | ./sfx/chestlrg.wav |
d5e3f378b894a8ee179e2a2d7e17eb86d9c267bd | ./sfx/buzzmed.wav |
31d60649b6797626e38421b32a27eac6a9c84df6 | ./sfx/mystery.wav |
8a397e81ea87985ebe0244414ab21ad47d7228f9 | ./sfx/walker.wav |
d5b4c7eec94b3c88f33f792db74b539829ef21e3 | ./sfx/cantina.wav |
200886036f2af0e382e9b3986542e35662f99929 | ./sfx/locator.wav |
b0ada8bbd7c352a2b489faa9fdb640abc8cd220a | ./sfx/pistol.wav |
4e64a3a79a879c91c35bf614e5b81965ecf434eb | ./sfx/buzzlow.wav |
7c45cbecd946fee69b515bb01c436bd82acc0d14 | ./sfx/emptheme.wav |
e8e40ba4bd82630434b826a3265edc8549ae34b3 | ./sfx/wookie.wav |
7791b4cad2437e10169c1f60d47a0fae953f167a | ./sfx/armforce.wav |
40e6664e59ed24e7107d5785e6bf72375546e576 | ./sfx/blaster.wav |
1d301d467868f8727e7327a81e6dc0a4ac4d7a9c | ./sfx/doorelec.wav |
72d23409767760589c08e52495ab4136e5af1ee6 | ./sfx/saberout.wav |
ef059f05dcb04d32f0af1fbd7163b962e6e4fd0d | ./sfx/rifle.wav |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./sfx/switch-7.wav |
5c8c54eb51f19cdb0e3745e30cf5d9dccdb25151 | ./sfx/switch-6.wav |
caa7ad2b6e00e02ebb8f136c33d372a0bb7d8b1c | ./sfx/vader.wav |
071bd82aff663e50aa78e8d3fe2001f6aab1f7d8 | ./sfx/eep.wav |
978cebdf7023a24acd2b0e0795c034da1c9e47b3 | ./sfx/banghuge.wav |
717b92788485092181957614fd3b156f4549b51c | ./sfx/switch-4.wav |
3191a59954f98347c55be705c27064d1c96ce825 | ./sfx/switch-5.wav |
9bd9dbe0bac4fe541c620bac501cfbaf179a29ce | ./sfx/truckin.wav |
46323d03602a3d97a8b46bebf68cd5dcdc6ad0cc | ./sfx/switch-1.wav |
e0ab059defcc74c0f44c246750f442203930471a | ./sfx/speeder.wav |
8e9962d0069c0b74c07ce61005bf9dc3003b9f9c | ./sfx/banglrg.wav |
55ebccfc7ea4327ffda2607e081c4d99fcccdc5d | ./sfx/hugedoor.wav |
7af931273d6374af73538b1580ff04f287de6ded | ./sfx/schwing.wav |
1b4293242d61461914623ffad36867537ab199d5 | ./sfx/transprt.wav |
7995af7e4cd2b97e5419e1ea93dfcb5eb7c356c8 | ./sfx/tryagain.wav |
5f384cd6565305544f06f650a64b01f4f15c4bbb | ./sfx/switch-2.wav |
690c39b1ea1cdf86e28cf1335cb620c3ba92727a | ./sfx/youwin.wav |
97269a0f50b7bf37530d4c0b7ec0ce9089c8718d | ./sfx/force.wav |
5687e94a1faac7dbe75881e9dd6c1c8fe031984d | ./sfx/armed.wav |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./sfx/shpoonk.wav |
dd9ce24759ac8ddf5e09f6b848c5dd71cd9a1b6c | ./sfx/switch-3.wav |
3d0f7ad1aa43aa7d2e8daf3c509d307185fd252e | ./sfx/r2d2-2.wav |
d55ff1a47a2a1a08c26990a713e2310546461703 | ./sfx/bong.wav |
d7e352947ee21ef48b1f020c42c999820caa176d | ./sfx/r2d2-1.wav |
bdc3addce338d60d2b4e4fe3452508fcfdd0f7a4 | ./sfx/saber.wav |
3fb938e254ba8b9426b38857d02de48c998db9a2 | ./sfx/xwingin.wav |
9e2f78a639a27685f9184eef514af521d3f9223b | ./sfx/bleepsml.wav |
9920d7446a2f259f0a62dffd0e61e30fb7eb4dfd | ./sfx/buzzhigh.wav |
5b5e4581d77527afc79163fdcc31f0b4ded65005 | ./sfx/chestsml.wav |
b710cd2f427f742ee1202adf04d9caf242ea6026 | ./sfx/switch-8.wav |
3f2d782c4788ae1bfeed65103863c274d9978649 | ./sfx/tieby.wav |
833757378d9e8ad02c0a441439349402c627328d | ./sfx/impblst.wav |
419cc1734f33953219b94d9316f2780a1655aa7d | ./sfx/blip.wav |
b55808ae16478322f62b3a510b5618addca12cfc | ./sfx/saberswg.wav |
c7bde605481cc7450397fc966d2edcf949eddaf2 | ./sfx/xwingout.wav |
3f8f63d62dababaed9c9fd0da3c5687fc8d6d91c | ./sfx/truckout.wav |
79a9a56abd0525f2e2980009a8ae313cd91f382c | ./sfx/flourish.wav |
2722f7599fe8ac7e4d3876276aea3c71fdd53327 | ./sfx/chirp.wav |
75b1ebef0a2b29f14d787fe6ca8af3d2fc15af5b | ./sfx/opening.wav |
37e222b09f2b1cf86dfbbac5cd06ce1d7bb79c11 | ./sfx/splash.wav |
2d4d0af951307083b7cce9840e7ee4d3013d2590 | ./sfx/riflblst.wav |
ccbe0e1d23f353e2ff5f8a50a41cbf3e1b62285a | ./sfx/mapcls.wav |
65f50467bd6331d13498d547c9d08dc00b2ebcca | ./sfx/xwingby.wav |
7640aefae2ec587bfeeb3456a66fa57e6d3b6d06 | ./sfx/crash.wav |
ebddf621f032f619d14b3b4eae2296fe58413efa | ./sfx/bangmed.wav |
e8febb3a41d4eef2587dad9cd5e2719d7392635d | ./sfx/push.wav |
cd5db260b3b0879e48064c65eee061942f955ced | ./sfx/nogo.wav |
5e7bc1330365191feecd53d8595ee1da96b74b85 | ./sfx/moverock.wav |
b1e5be033b13b24806ea961f7998fdffe2f81803 | ./sfx/doorpnum.wav |
13e914ad378bcef9a7b030200e0dc7a66c078473 | ./wavemix.ini |
b6d1ac4d9f165403898531341d13885c770d4177 | ./MSVCRT40.DLL |
d44d3a01bdb0cee31163466ba91614eba8ffc21d | ./YodaDemo.cnt |
21265b5d3d600ecd9869a88c70096b3e0ea3c6b2 | ./wavmix32.dll |
07d1ce2f03e8596b068f1972c897f2615ca83743 | ./YodaDemo.exe |
Indiana Jones and his Desktop Adventures
Indiana Jones and his Desktop Adventures (English)
sha1 | Common Name |
---|---|
4095a9168865b07f09f19d82d33c6f31c8f065f8 | ./WHIP.WAV |
8230c23a28266b2f1ae919d8827b3da41ca071d3 | ./ROAR.WAV |
893ef56002780a810f86b0ef25bac36056ac1f70 | ./GUNSHOT.WAV |
add15e7a707f6a9bdad4315d4ea4122616f998d0 | ./DESKADV.EXE |
6a854968594d232d83e8dc6938f89d6509eae715 | ./ARROW.WAV |
a0f074324ae7f26ad3432204c4f956bd021c2f6d | ./THEME.MID |
4956f47846c4b0cb07eb58b995149c10948586b6 | ./THEMW3.MID |
834a2ad22aef7ddbede869bced2e4c7a00cdb0c9 | ./EXPLODE.WAV |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./INDYHURT.WAV |
5d5d3f95816e8ab39b899fda5e8922b039fbc43b | ./EEP.WAV |
5ae192363d2cb894ed8b3581dc7d485e90e2b9d1 | ./MACHETE.WAV |
6eb197cbcfb06848662c7e2fea2211c0abf03693 | ./VICTORY.MID |
ef9e4f363a8692509632ecde4ab9436ea081f31f | ./SCHWING.WAV |
8bfc1b0ff35a1274c424fb354820e8c808fb0133 | ./EERIE.MID |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SHPOONK.WAV |
829675f1515db77378f0704619fe68dbaf51a8eb | ./SPEAR.WAV |
8d911b8fb12f2b1a7334c05ac786fbe8074fbff6 | ./DESKTOP.DAW |
5b85e81efdcb70c62a2c6d97b0afac4f674a7e27 | ./FLOURISH.MID |
9f83ecdfe7e66893837daca54d66cdfe3a2fc7c6 | ./WALLPPR.BMP |
d886abc61fe71bd816fc9a32bf6ff55fbd331ba7 | ./DESKADV.HLP |
f32bc99e42cf6de9234004aeeca035492ba17d57 | ./DEFEAT.MID |
5be5f69e44d346041f65e2f93ac8c40ccf3d5738 | ./PUSH.WAV |
5fa53bc8756a5876bfdd1ed0b19d25be49bbd4b5 | ./NOGO.WAV |
9f0b6e7da8b3e12833fa4802411ff632fb7a60f7 | ./DOOR.WAV |
75f4180fd4e8435c8b151509393b2dd6a1ed283a | ./SWITCH.WAV |
Indiana Jones and his Desktop Adventures (French)
sha1 | Common Name |
---|---|
4095a9168865b07f09f19d82d33c6f31c8f065f8 | ./WHIP.WAV |
8230c23a28266b2f1ae919d8827b3da41ca071d3 | ./ROAR.WAV |
893ef56002780a810f86b0ef25bac36056ac1f70 | ./GUNSHOT.WAV |
f945b03e6259fde34c50e8baf23e5c005a7ed510 | ./DESKADV.EXE |
6a854968594d232d83e8dc6938f89d6509eae715 | ./ARROW.WAV |
a0f074324ae7f26ad3432204c4f956bd021c2f6d | ./THEME.MID |
4956f47846c4b0cb07eb58b995149c10948586b6 | ./THEMW3.MID |
834a2ad22aef7ddbede869bced2e4c7a00cdb0c9 | ./EXPLODE.WAV |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./INDYHURT.WAV |
5d5d3f95816e8ab39b899fda5e8922b039fbc43b | ./EEP.WAV |
5ae192363d2cb894ed8b3581dc7d485e90e2b9d1 | ./MACHETE.WAV |
6eb197cbcfb06848662c7e2fea2211c0abf03693 | ./VICTORY.MID |
ef9e4f363a8692509632ecde4ab9436ea081f31f | ./SCHWING.WAV |
8bfc1b0ff35a1274c424fb354820e8c808fb0133 | ./EERIE.MID |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SHPOONK.WAV |
829675f1515db77378f0704619fe68dbaf51a8eb | ./SPEAR.WAV |
23a4eb2332c3d90e3e71b531034309ee207266b6 | ./DESKTOP.DAW |
5b85e81efdcb70c62a2c6d97b0afac4f674a7e27 | ./FLOURISH.MID |
9f83ecdfe7e66893837daca54d66cdfe3a2fc7c6 | ./WALLPPR.BMP |
c96ec6315d4de9dbc6ea8e8bc32150f961fb0d07 | ./DESKADV.HLP |
f32bc99e42cf6de9234004aeeca035492ba17d57 | ./DEFEAT.MID |
5be5f69e44d346041f65e2f93ac8c40ccf3d5738 | ./PUSH.WAV |
5fa53bc8756a5876bfdd1ed0b19d25be49bbd4b5 | ./NOGO.WAV |
9f0b6e7da8b3e12833fa4802411ff632fb7a60f7 | ./DOOR.WAV |
75f4180fd4e8435c8b151509393b2dd6a1ed283a | ./SWITCH.WAV |
Indiana Jones and his Desktop Adventures (Spanish)
sha1 | Common Name |
---|---|
4095a9168865b07f09f19d82d33c6f31c8f065f8 | ./WHIP.WAV |
8230c23a28266b2f1ae919d8827b3da41ca071d3 | ./ROAR.WAV |
893ef56002780a810f86b0ef25bac36056ac1f70 | ./GUNSHOT.WAV |
c996f07955175daea25d8a1dbe571d48851cf7d9 | ./DESKADV.EXE |
6a854968594d232d83e8dc6938f89d6509eae715 | ./ARROW.WAV |
a0f074324ae7f26ad3432204c4f956bd021c2f6d | ./THEME.MID |
4956f47846c4b0cb07eb58b995149c10948586b6 | ./THEMW3.MID |
834a2ad22aef7ddbede869bced2e4c7a00cdb0c9 | ./EXPLODE.WAV |
6a03617143cb01d69fa50589e192f59b787d5ca8 | ./INDYHURT.WAV |
5d5d3f95816e8ab39b899fda5e8922b039fbc43b | ./EEP.WAV |
5ae192363d2cb894ed8b3581dc7d485e90e2b9d1 | ./MACHETE.WAV |
6eb197cbcfb06848662c7e2fea2211c0abf03693 | ./VICTORY.MID |
ef9e4f363a8692509632ecde4ab9436ea081f31f | ./SCHWING.WAV |
8bfc1b0ff35a1274c424fb354820e8c808fb0133 | ./EERIE.MID |
8e6b3a02e9fa3293b87899336a8189568bb8bbf4 | ./SHPOONK.WAV |
829675f1515db77378f0704619fe68dbaf51a8eb | ./SPEAR.WAV |
ac2e926c2a7374197d299d4b7625ed118bc7fbda | ./DESKTOP.DAW |
5b85e81efdcb70c62a2c6d97b0afac4f674a7e27 | ./FLOURISH.MID |
73649fb9f2a773505a06c31a8e024eec3c5e7552 | ./WALLPPR.BMP |
e709998bac74b08ad507a742bbbf8c20a5899fc0 | ./DESKADV.HLP |
f32bc99e42cf6de9234004aeeca035492ba17d57 | ./DEFEAT.MID |
5be5f69e44d346041f65e2f93ac8c40ccf3d5738 | ./PUSH.WAV |
5fa53bc8756a5876bfdd1ed0b19d25be49bbd4b5 | ./NOGO.WAV |
9f0b6e7da8b3e12833fa4802411ff632fb7a60f7 | ./DOOR.WAV |
75f4180fd4e8435c8b151509393b2dd6a1ed283a | ./SWITCH.WAV |