Common hacking questions
This page contains answers to various questions and obstacles that hackers (new and old) may come across while hacking Oracle of Ages or Seasons.
General
Where can I find other Oracles hackers?
The most active place is the official Discord server (https://discord.gg/wCpPPNZ). Users who actively participate in or have knowledge of Oracles hacking have the "Wind Fish" role.
Should I hack Ages or Seasons?
Take your pick! Ages items are available in Seasons and vice-versa in the hack-base branch, so that need not be a factor. The main considerations are:
- Do you want the dual overworlds of Ages, or the single large overworld with 4 variants of Seasons? The seasonal map variants are tied together more closely than the Ages past/present maps (there is only one overworld map, for example).
- As an example, if you want one dark-world style alternate overworld, Ages would be the better choice.
- Are there any objects in one game that are unavailable in the other which you need? (Scroll through the object list in LynnaLab to see if the ones you need are there)
While it's technically possible to port most stuff from one game to another, it would be much easier to simply choose the game that's closest to your needs if you don't have the technical expertise to do so.
Can I make a ROM hack without knowing how to code?
Takes a deep breath
Kind of. You can get started with using LynnaLab and designing custom levels without doing any coding. You might even be able to design a whole dungeon without writing any code.
However, at some point you're going to want to do something specific that the game can't do for you. Maybe you'll just want to spawn a bridge in a certain place, or spawn some enemies when you press a button, or make an NPC move around in a rudimentary cutscene. All of these things require coding of some kind.
One of the primary goals of the disassembly is to lower the barrier of entry to code hacking as much as possible. The code is decently well documented, and you should NEVER have to pull out a hex editor. An immense amount of work has been put into this, so if you're serious about making ROM hacks, meet us halfway here.
Coding can be divided into scripting and assembly hacking. The former is not as difficult, so it's recommended to start there if you want to create any custom events.
See the tutorials page for various guides, including some tutorials on code hacking.
Hacking with LynnaLab / Oracles-disasm
How do I set Link's spawn position at the start of the game?
There is a table named "initialFileVariables" at the very end of code/fileManagement.s:
; Initial values for variables in the c6xx block.
initialFileVariables:
.db <wTextSpeed, $02
.db <wc608, $01
.db <wLinkName+5, $00 ; Ensure names have null terminator
.db <wKidName+5, $00
.db <wObtainedTreasureFlags, 1<<TREASURE_PUNCH
.db <wMaxBombs, $10
.db <wLinkHealth, $10 ; 4 hearts (gets overwritten in standard game)
.db <wLinkMaxHealth, $10
.ifdef ROM_AGES
; Initial spawn location
.db <wDeathRespawnBuffer.group, $00
.db <wDeathRespawnBuffer.room, $8a
.db <wDeathRespawnBuffer.y, $38
.db <wDeathRespawnBuffer.x, $48
.db <wDeathRespawnBuffer.facingDir, $00
.db <wJabuWaterLevel, $21
.db <wPortalGroup, $ff
.db <wPirateShipRoom, $b6
.db <wPirateShipY, $48
.db <wPirateShipX, $48
.db <wPirateShipAngle, $02
.else ;ROM_SEASONS
; Initial spawn location
.db <wDeathRespawnBuffer.group, $00
.db <wDeathRespawnBuffer.room, $a7
.db <wDeathRespawnBuffer.y, $38
.db <wDeathRespawnBuffer.x, $48
.db <wDeathRespawnBuffer.facingDir, $02
.endif
.db $00
Modify the data starting from the highlighted line to set the group / room / position you spawn in (wDeathRespawnBuffer.group, wDeathRespawnBuffer.room, etc). (Those lines are for Ages; for Seasons, see the equivalent lines after the ".else".)
By default, you spawn in group 0, room $8a.
NOTE: Changes made here only apply to newly created files, NOT to files that have been created already, even if you haven't done anything in them yet.
See Useful_patches#Remove_Beginning_Locks
How do I handle the Animal Companion regions?
See Room packs.
Oracle of Ages stuff
I'm using a script in a past map from $f0-$f5, but it's behaving strangely.
Maps $f0-$f5
(inclusive) in the past overworld (and past underwater) are unused because their room flags are used to remember the 6 vine sprout positions. As such, moving a vine will also change the room flags in those rooms, which can mess up your scripts.
Even if you're not using vines, their initial positions can still mess up your scripts. You can fix this by going to address $129e8
in your ROM and changing these 6 bytes all to 00:
41 22 16 35 18 53
You will need to start a new game for this change to take effect.
You can also edit these to other values to change the initial positions of the vines (although changing their rooms is more complicated, since most vine behaviour is hardcoded with "map scripts", as ZOLE calls them.)
Caveats
- Using bombable walls that go left or right in an indoor area in the past overworld/underwater will cause their corresponding room flags to be set in the present overworld/underwater. As a result, not only will it not remember that the wall was destroyed, but it may screw up the flags in the corresponding rooms in the present.
- Bombable walls going up/down aren't affected by this issue, but those kinds don't attempt to set the "wall blown up" flag in the adjacent room (for indoors areas only; they work properly in dungeons).
- See the "setRoomFlagsForUnlockedKeyDoor_overworldOnly" function in the disassembly.
- See the Bug List for more.
Hardcoded things
Not all rooms are equal. Some have hardcoded behaviour.
Ages
- Symmetry City present has a "smooth palette transition" when entering or exiting the area, but it is ignored when the global flag for restoring the tuni nut is unset.
- See
checkSymmetryCityPaletteTransition (01:4862)
.
- See
- Bombs are hardcoded to trigger a cutscene in room $0050, the place where you get the bomb upgrade, if they fall into a hazard (water, lava, or a hole).
- See
_bombUpdateThrowingAndCheckDelete (07:5530)
.
- See
- The cane of somaria doesn't work in Patch's minigame room.
- See
@checkBlockCanAppear (07:5e02)
.
- See
- In Nayru's house, Link will enter a "sleeping" state by walking into a bed at a specific position.
- Octogon (the boss) is hardcoded to set flags in specific rooms, meaning he may not work properly if relocated.
Seasons
- Snake's remains entrance is hardcoded to be darkened before the torches are lit.
- The compass is hardcoded to chime in the unicorn cave's boss key room (for some reason).