Oculus Runes

From LSWiki

(Difference between revisions)
Jump to: navigation, search
Revision as of 15:02, 15 February 2024 (edit)
Iosin (Talk | contribs)
(Tintin++)
← Previous diff
Current revision (15:15, 30 October 2024) (edit)
Moxomatosis (Talk | contribs)
(Added a web based solver.)
 
Line 1: Line 1:
 +==Online==
 +A version of the Python offline solver (see below) is available at https://moxomatosis.github.io/oculus.html. You need to enter the state of the Oculus as a sequence of letters matching the colors. When a color points up, enter the letter in uppercase, otherwise use lowercase. An example would be rOygBiV. The output will be a sequence of flips to perform to get the proper result. Note that the output may be upside down, so you may need to flip the Oculus to complete the puzzle.
 +
 +==ZMUD==
The first line directly under the pattern # is the actual trigger pattern. The rest is the execution code. The first line directly under the pattern # is the actual trigger pattern. The rest is the execution code.
These triggers (put them in a class folder so you can easily disable them later) produce two variables: @oculus, which counts how many times the oculus has been rotated, and @count, which tells the script how many times runes have been flipped. You only get 15 moves, so when the 15th move occurs, it restarts the script. When the oculus has been rotated 5 times, the script attempts to make you enter the portal (assuming success.) If that fails, it moves on to flipping the current first rune until count restarts it. These triggers (put them in a class folder so you can easily disable them later) produce two variables: @oculus, which counts how many times the oculus has been rotated, and @count, which tells the script how many times runes have been flipped. You only get 15 moves, so when the 15th move occurs, it restarts the script. When the oculus has been rotated 5 times, the script attempts to make you enter the portal (assuming success.) If that fails, it moves on to flipping the current first rune until count restarts it.

Current revision

Contents

Online

A version of the Python offline solver (see below) is available at https://moxomatosis.github.io/oculus.html. You need to enter the state of the Oculus as a sequence of letters matching the colors. When a color points up, enter the letter in uppercase, otherwise use lowercase. An example would be rOygBiV. The output will be a sequence of flips to perform to get the proper result. Note that the output may be upside down, so you may need to flip the Oculus to complete the puzzle.

ZMUD

The first line directly under the pattern # is the actual trigger pattern. The rest is the execution code. These triggers (put them in a class folder so you can easily disable them later) produce two variables: @oculus, which counts how many times the oculus has been rotated, and @count, which tells the script how many times runes have been flipped. You only get 15 moves, so when the 15th move occurs, it restarts the script. When the oculus has been rotated 5 times, the script attempts to make you enter the portal (assuming success.) If that fails, it moves on to flipping the current first rune until count restarts it.

It took me about an hour to work out all the kinks and try different iterations of this script, but this is the simplest and most effective version. I had a success after about five minutes of running it.

Special Note: The rest of the Illuminatorium puzzles took me less than 5 minutes a piece to complete. I spent about three HOURS trying to solve the Oculus runes by traditional method (pen and paper) and eventually decided I'd had enough of it.

To start the script execution, turn off triggers and "flip first rune" until you get a message saying colors flicker across your oculus. Then turn triggers on, and "look at runes on oculus" one time. The rest is automated until success or you get disconnected from the MUD.

Once you've entered the portal, you need to 'place oculus on pedestal.' You could add it to the enter portal trigger if necessary.

11/28/2022: This script still works to solve the quest via brute force. Changed one pattern to reflect an updated failure message. ("You do not know how to 'enter'." became "You do not see a portal here.")

Pattern 1

The first rune is %1 and points %2.  The second rune is %3 and points %4.  The third rune is %5 and points %6.
#IF %2=downward {
 flip first rune
 #wait 1000
 look at runes on oculus
 } {
 #IF %4=downward {
   flip second rune
   #wait 1000
   look at runes on oculus
   } {
   #IF %6=downward {
     flip third rune
     #wait 1000
     look at runes on oculus
     } {
     rotate oculus left
     #MATH oculus (@oculus+1)
     #IF @oculus=5 {
       #MATH oculus (@oculus*0)
       enter portal
       } {look at runes on oculus}
     }
   }
 }

Pattern 2

The Illuminatorium Oculus reacts to your proximity
#MATH count (@count+1)

Pattern 3

You see colors flicker across the Illuminatorium Oculus as its runes reorient themselves.
#MATH count (@count*0)
look at runes on oculus

Pattern 4

You do not see a portal here.
flip first rune
#wait 1000
#IF @count<14 {enter portal}
#IF @count=14 {flip first rune}


Mudlet Port

Before using the triggers, Set Usable Columns to 200 and Toggle Columns Override to Off in the Terminal Setup Menu; when finished go back to default.

Another thing you could do is to set the in game filter OOC - and set it on again OOC + when finished.

Trigger 1

(perl regex): The first rune is (\w+) and points (\w+).  The second rune is (\w+) and points (\w+).  The third rune is (\w+) and points (\w+).
runeonedir = matches[3]
runetwodir = matches[5]
runethreedir = matches[7]
if runeonedir == "downward" then
  send("flip first rune") 
  tempTimer(1.5, [[send("look at runes on oculus")]])
elseif runetwodir == "downward" then
   send("flip second rune")
   tempTimer(1.5, [[send("look at runes on oculus")]])
elseif runethreedir == "downward" then
   send("flip third rune")
   tempTimer(1.5, [[send("look at runes on oculus")]])
else 
   send("rotate oculus left")
   oculus = oculus or 0
   oculus = oculus + 1
   if oculus == 5 then
       oculus = 0
       send("enter portal")
   else
       send("look at runes on oculus")
   end
end

Trigger 2

(substring): The Illuminatorium Oculus reacts to your proximity
count = count or 0
count = count + 1

Trigger 3

(substring): You see colors flicker across the Illuminatorium Oculus as its runes reorient themselves.
count = 0
send("look at runes on oculus")

Trigger 4

(substring 1): That doesn't make sense.
(substring 2): You do not see a portal here.
function countit()
   if count < 14 then
       send("enter portal")
   end
   if count == 14 then
       send ("flip first rune")
   end
end
send("flip first rune")
tempTimer(1, countit)


Offline Python

#!/usr/bin/env python3

from collections import deque
import sys

goal = 'ROYGBIV'
goal_1 = list(goal.lower())
goal_2 = list(goal.upper())

def all_shifts(shifts, pattern):
    results = {}
    for i in range(len(pattern)):
        new_arr = list(pattern)
        char = pattern[i].lower() if pattern[i].isupper() else pattern[i].upper()
        new_pos = ((i + 2) % (len(pattern) - 1)) + 1
        new_arr.pop(i)
        new_arr.insert(new_pos, char)
        rotate_arr = deque(new_arr)
        while rotate_arr[0] not in ['R', 'r']:
            rotate_arr.rotate(1)
        results[shifts + pattern[i]] = list(rotate_arr)
    return results


def main():
    if len(sys.argv) < 2:
        print('Usage: %s <starting pattern>' % (sys.argv[0]))
        print('Format for the pattern is RoYGBiV where capital is up and lowercase is down, in the order the runes are presently')
        sys.exit(1)
    else:
        pattern = sys.argv[1]
        for c in pattern:
            if c.upper() not in goal:
                print('Invalid color %s' % (c))
                sys.exit(1)
    print('origin: ' + str(list(pattern)))
    loops = 1
    states = {}
    states[0] = all_shifts(, pattern)
    while loops < 14:
        for shifts, state in iter(states[loops - 1].items()):
            new_states = all_shifts(shifts, state)
            if goal_1 in new_states.values():
                print(str([ k for k in new_states if new_states[k] == goal_1 ]) + ' => ' + str(goal_1))
                sys.exit(0)
            if goal_2 in new_states.values():
                print(str([ k for k in new_states if new_states[k] == goal_2 ]) + ' => ' + str(goal_2))
                sys.exit(0)
            if not loops in states:
                states[loops] = {}
            states[loops].update(new_states)
        loops += 1
    print("Couldn't find a solution")

if __name__ == "__main__":
    main()

Tintin++

This solution uses only basic functions of Tintin. It's important to make sure that your screen is big enough so none of the trigger elements wrap around and that you have the Oculus identified. It first flips all the runes on the Oculus upwards and will then flip only the first rune until the Oculus resets or the portal appears.

#ALIAS {r} {look at runes on oculus}
#ACTION {The third rune is %1 and points downward} {flip third rune} {1}
#ACTION {The second rune is %1 and points downward} {flip second rune} {2}
#ACTION {The first rune is %1 and points downward} {flip first rune} {3}
#ACTION {The first rune is %1 and points upward.  The second rune is %2 and points upward.  The third rune is %3 and points upward.} {rotate disc left}
#ACTION {You can see three runes} {#ticker q {flip first rune} 2}
#ACTION {You see colors flicker across the Illuminatorium Oculus as its runes} {#unticker q;#delay 1 r;#delay 2 r;#delay 3 r;#delay 4 
r;#delay 5 r;#delay 6 r;#delay 7 r;#delay 8 r;#delay 9 r;#delay 10 r}
#ACTION {materializes in the air} {#unticker q;enter gold portal;place oculus on pedestal}
Personal tools