I have some additions to beorn080's tips...
Pets: Choose the little girl... but not becaues of loli. Little girl has the largest number of equipment slots among the starting pets, and she can use whatever equipment you don't use yourself. That makes her the best starting pet.
Escort quests: Don't do those "protect me" escort quests, those can be very dangerous. Do those "escort me to doctor" ones. Those sick people can fight. Yup. And there's no assassins going after them.
Puppy Cave: It's actually a good place to go. Go in, stay around the stairs and pickup everything nearby. Then back to town, sell them, rinse and repeat. Puppy cave instantly regenerates when you leave a level, so don't leave items on the ground.
is a great resource for how to play Elona.
For cheating, well... I have an
script here... it's a script for save scumming (i.e. save and reload) conveniently. To use, put everything in the following spoiler box into a file with ".ahk" extension. Then download and install AutoHotKey, and instead of running Elona.exe, run the .ahk script instead.
The first time you run it, it will ask you which folder Elona is in. Then it will write an INI file to remember that. It will create a new folder "SaveScum" alongside Elona's save folder.
When you feel you just did something great, exit Elona, select your save in the lower section, and press Backup Selected. Enter a description (or just press Enter for a date). Later if you screw up, select the backup in the upper section, and press Restore Selected.
; Save Scumming Script for Elona
; Version
VERSION := 1.0
; Constants
ELONA_EXE_NAME := "Elona.exe"
SAVE_FOLDER_NAME := "save"
BACKUP_FOLDER_NAME := "SaveScum"
SAVE_PATTERN := "sav_*"
DATE_TIME_FORMAT := "yyyy-MM-dd HH:mm:ss"
DATE_TIME_FORMAT_FILE := "yyyy-MM-dd HH.mm.ss"
BACKUP_SAVE_NAME_PATTERN := "sav_(.+) - (.+)"
RESTORE_PATTERN := "(sav_.+) - .+"
SAVE_NAME_PATTERN := "sav_(.+)"
; UI Constants
GROUPBOX_STYLE := "w620 h260"
LISTVIEW_STYLE := "AltSubmit Grid SortDesc LV0x20 r10 w600 xp+10 yp+20"
FIRST_GROUP_BUTTON_STYLE := "xp yp+205 w200"
SECOND_GROUP_BUTTON_STYLE := "xp+400 yp+0 w200"
MAIN_BUTTON_STYLE := "w200"
BROWSE_EDIT_STYLE := "R1 W430"
BROWSE_BUTTON_STYLE := "w100"
STATUS_BAR_STYLE := "Border w620 h15"
; Messages
MSG_TITLE := "Elona Save Scum Made Easy"
MSG_ELONA_FOLDER := "Elona Folder: "
MSG_LOCATE_ELONA := "Please locate Elona's installation folder"
MSG_BACKUP_SAVE := "Backup Save(s)"
MSG_SAVE := "Save(s) In Use"
MSG_BACKUP_LIST_COLUMNS := "Date |Folder |Character |Description"
MSG_SAVE_LIST_COLUMNS := "Date |Folder |Character "
MSG_BROWSE := "&Browse"
MSG_RESTORE := "&Restore Selected"
MSG_BACKUP := "&Backup Selected"
MSG_LAUNCH := "Launch &Elona"
MSG_DELETE := "Delete Selected"
MSG_EXIT := "E&xit"
MSG_REFRESH := "Re&fresh"
MSG_ENTER_DESCRIPTION := "Enter a description for the save game. Leave blank for a timestamp."
MSG_TITLE_DESCRIPTION := "Enter Description"
MSG_ALREADY_EXIST := "Folder already exists"
MSG_BACKUP_OVERWRITE := "Backup already exists. Overwrite?"
MSG_SAVE_OVERWRITE := "Save already exists. Overwrite?"
MSG_TITLE_CONFIRM := "Confirmation Required"
MSG_DELETE_PREFIX := "Really delete"
MSG_DELETE_SUFFIX := "?"
; Status
STATUS_UNINITIALIZED := "Not Initialized"
STATUS_READY := "Ready"
STATUS_COPYING := "Copying..."
STATUS_DELETING := "Removing..."
; Error Messages
ERROR_TITLE := "Error"
ERROR_ELONA_NOT_FOUND := "Elona cannot be located"
ERROR_NO_BACKUP_SELECTED := "No backup selected"
ERROR_NO_SAVE_SELECTED := "No save selected"
ERROR_NO_DESCRIPTION := "No description"
; INI
INI_FILE := "ElonaSaveScum.ini"
INI_SECTION := "Config"
INI_ELONA := "Elona"
; Variables used throughout this script, declared first
ElonaFolder :=
ElonaExe :=
SaveFolder :=
BackupFolder :=
SelectedSaveFolder :=
SelectedBackupFolder :=
; Build GUI
GoSub BuildGUI
; Initialize data
GoSub InitData
; Kick start folder select if empty
If (ElonaFolder = "")
{
GoSub Browse
}
; Launch main GUI
Gui, Show, AutoSize Center, %MSG_TITLE% %VERSION%
GuiControl, Focus, ButtonLaunch
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Functions
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; SetStatus - Set text in status bar
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SetStatus(Data)
{
GuiControl, Text, StatusBar, %Data%
}
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Subroutines
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; BuildGUI - Contruct GUI in a disabled state
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BuildGUI:
Gui, Add, Text, Section xm, %MSG_ELONA_FOLDER%
Gui, Add, Edit, %BROWSE_EDIT_STYLE% ys ReadOnly vElonaPath
Gui, Add, Button, %BROWSE_BUTTON_STYLE% ys gBrowse, %MSG_BROWSE%
Gui, Add, GroupBox, Section xm %GROUPBOX_STYLE%, %MSG_BACKUP_SAVE%
Gui, Add, ListView, %LISTVIEW_STYLE% vBackupListView gBackupSelected, %MSG_BACKUP_LIST_COLUMNS%
Gui, Add, Button, Disabled %FIRST_GROUP_BUTTON_STYLE% vButtonRestore gRestoreSave, %MSG_RESTORE%
Gui, Add, Button, Disabled %SECOND_GROUP_BUTTON_STYLE% vButtonBackupDelete gBackupDelete, %MSG_DELETE%
Gui, Add, GroupBox, Section xm %GROUPBOX_STYLE%, %MSG_SAVE%
Gui, Add, ListView, %LISTVIEW_STYLE% vSaveListView gSaveSelected, %MSG_SAVE_LIST_COLUMNS%
Gui, Add, Button, Disabled %FIRST_GROUP_BUTTON_STYLE% vButtonBackup gBackupSave, %MSG_BACKUP%
Gui, Add, Button, Disabled %SECOND_GROUP_BUTTON_STYLE% vButtonSaveDelete gSaveDelete, %MSG_DELETE%
Gui, Add, Button, Default Disabled %MAIN_BUTTON_STYLE% Section xm vButtonLaunch gLaunch, %MSG_LAUNCH%
Gui, Add, Button, %MAIN_BUTTON_STYLE% ys gRefresh, %MSG_REFRESH%
Gui, Add, Button, %MAIN_BUTTON_STYLE% ys gExit, %MSG_EXIT%
Gui, Add, Text, Section xm vStatusBar %STATUS_BAR_STYLE%
SetStatus(STATUS_UNINITIALIZED)
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; InitData - Initialize data in variables and listview
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
InitData:
; Check INI for paths to resources
IniRead, ElonaFolder, %INI_FILE%, %INI_SECTION%, %INI_ELONA%, %A_Space%
If (ElonaFolder != "")
{
GuiControl, Text, ElonaPath, %ElonaFolder%
; Check validity
IfExist %ElonaFolder%\%ELONA_EXE_NAME%
{
; Initialize variables
ElonaExe = %ElonaFolder%\%ELONA_EXE_NAME%
SaveFolder = %ElonaFolder%\%SAVE_FOLDER_NAME%
BackupFolder = %ElonaFolder%\%BACKUP_FOLDER_NAME%
; Create backup folder if not exist
IfNotExist, %BackupFolder%
{
FileCreateDir, %BackupFolder%
}
; Set controls
GuiControl, Enable, ButtonLaunch
GuiControl, Disable, ButtonRestore
GuiControl, Disable, ButtonBackup
GuiControl, Disable, ButtonSaveDelete
GuiControl, Disable, ButtonBackupDelete
; Read list of saves in backup
Gui, ListView, BackupListView
LV_Delete()
Loop, %BackupFolder%\%SAVE_PATTERN%, 2, 0
{
CharacterName := RegExReplace(A_LoopFileName, BACKUP_SAVE_NAME_PATTERN, "$1")
SaveDescription := RegExReplace(A_LoopFileName, BACKUP_SAVE_NAME_PATTERN, "$2")
FileGetTime, SaveTime, %BackupFolder%\%A_LoopFileName%
FormatTime, SaveTimeString, %SaveTime%, %DATE_TIME_FORMAT%
LV_Add("", SaveTimeString, A_LoopFileName, CharacterName, SaveDescription)
}
; Read list of saves in save
Gui, ListView, SaveListView
LV_Delete()
Loop, %SaveFolder%\%SAVE_PATTERN%, 2, 0
{
CharacterName := RegExReplace(A_LoopFileName, SAVE_NAME_PATTERN, "$1")
FileGetTime, SaveTime, %SaveFolder%\%A_LoopFileName%
FormatTime, SaveTimeString, %SaveTime%, %DATE_TIME_FORMAT%
LV_Add("", SaveTimeString, A_LoopFileName, CharacterName)
}
SetStatus(STATUS_READY)
}
else
{
; Disable all controls
GuiControl, Disable, ButtonLaunch
GuiControl, Disable, ButtonRestore
GuiControl, Disable, ButtonBackup
GuiControl, Disable, ButtonSaveDelete
GuiControl, Disable, ButtonBackupDelete
; Destroy data
Gui, ListView, BackupListView
LV_Delete()
Gui, ListView, SaveListView
LV_Delete()
SetStatus(STATUS_UNINITIALIZED)
; Report error
MsgBox, 0, %ERROR_TITLE%, %ERROR_ELONA_NOT_FOUND%
}
}
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Event handlers
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Window closed
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GuiClose:
ExitApp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Browse Elona folder
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Browse:
FileSelectFolder, ElonaFolder, *%A_WorkingDir%, 0, %MSG_LOCATE_ELONA%
If ErrorLevel = 0
{
IniWrite, %ElonaFolder%, %INI_FILE%, %INI_SECTION%, %INI_ELONA%
GoSub InitData
}
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; A save selected
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SaveSelected:
If (A_GuiEvent == "I") or (A_GuiEvent == "F")
{
; Disable Restore
SelectedBackupFolder :=
GuiControl, Disable, ButtonRestore
GuiControl, Disable, ButtonBackupDelete
; Enable Backup?
Gui, ListView, SaveListView
RowNum := LV_GetNext()
If Not RowNum
{
SelectedSaveFolder :=
GuiControl, Disable, ButtonBackup
GuiControl, Disable, ButtonSaveDelete
}
else
{
LV_GetText(SelectedSaveFolder, RowNum, 2)
GuiControl, Enable, ButtonBackup
GuiControl, Enable, ButtonSaveDelete
}
}
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; A backup selected
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BackupSelected:
If (A_GuiEvent == "I") or (A_GuiEvent == "F")
{
; Disable Backup
SelectedSaveFolder :=
GuiControl, Disable, ButtonBackup
GuiControl, Disable, ButtonSaveDelete
; Enable Restore?
Gui, ListView, BackupListView
RowNum := LV_GetNext()
If Not RowNum
{
SelectedBackupFolder :=
GuiControl, Disable, ButtonRestore
GuiControl, Disable, ButtonBackupDelete
}
else
{
LV_GetText(SelectedBackupFolder, RowNum, 2)
GuiControl, Enable, ButtonRestore
GuiControl, Enable, ButtonBackupDelete
}
}
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Delete selected backup
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BackupDelete:
If (SelectedBackupFolder = "")
{
MsgBox, 0, %ERROR_TITLE%, %ERROR_NO_BACKUP_SELECTED%
}
else
{
NewName = %BackupFolder%\%SelectedBackupFolder%
Delete := True
MsgBox, 4, %MSG_TITLE_CONFIRM%, %MSG_DELETE_PREFIX% %NewName% %MSG_DELETE_SUFFIX%
IfMsgBox No
{
Delete := False
}
If Delete
{
SetStatus(STATUS_DELETING)
FileRemoveDir %NewName%, 1
SetStatus(STATUS_READY)
}
GoSub InitData
}
SelectedBackupFolder :=
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Delete selected save
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SaveDelete:
If (SelectedSaveFolder = "")
{
MsgBox, 0, %ERROR_TITLE%, %ERROR_NO_SAVE_SELECTED%
}
else
{
NewName = %SaveFolder%\%SelectedSaveFolder%
Delete := True
MsgBox, 4, %MSG_TITLE_CONFIRM%, %MSG_DELETE_PREFIX% %NewName% %MSG_DELETE_SUFFIX%
IfMsgBox No
{
Delete := False
}
If Delete
{
SetStatus(STATUS_DELETING)
FileRemoveDir %NewName%, 1
SetStatus(STATUS_READY)
}
GoSub InitData
}
SelectedSaveFolder :=
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Restore backup selected
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RestoreSave:
If (SelectedBackupFolder = "")
{
MsgBox, 0, %ERROR_TITLE%, %ERROR_NO_BACKUP_SELECTED%
}
else
{
NewName := RegExReplace(SelectedBackupFolder, RESTORE_PATTERN, "$1")
NewName = %SaveFolder%\%NewName%
Copy := True
IfExist, %NewName%
{
MsgBox, 4, %MSG_ALREADY_EXIST%, %MSG_SAVE_OVERWRITE%
IfMsgBox No
{
Copy := False
}
}
If Copy
{
SetStatus(STATUS_COPYING)
FileRemoveDir %NewName%, 1
FileCopyDir %BackupFolder%\%SelectedBackupFolder%, %NewName%, 1
SetStatus(STATUS_READY)
}
GoSub InitData
}
SelectedBackupFolder :=
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Add selected save to backup
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BackupSave:
If (SelectedSaveFolder = "")
{
MsgBox, 0, %ERROR_TITLE%, %ERROR_NO_SAVE_SELECTED%
}
else
{
InputBox, Description, %MSG_TITLE_DESCRIPTION%, %MSG_ENTER_DESCRIPTION%
If (Description = "")
{
; Assign default description
FormatTime, Description, , %DATE_TIME_FORMAT_FILE%
}
NewName = %BackupFolder%\%SelectedSaveFolder% - %Description%
Copy := True
IfExist, %NewName%
{
MsgBox, 4, %MSG_ALREADY_EXIST%, %MSG_BACKUP_OVERWRITE%
IfMsgBox No
{
Copy := False
}
}
If Copy
{
SetStatus(STATUS_COPYING)
FileRemoveDir %NewName%, 1
FileCopyDir %SaveFolder%\%SelectedSaveFolder%, %NewName%, 1
SetStatus(STATUS_READY)
}
GoSub InitData
}
SelectedSaveFolder :=
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Start Elona
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Launch:
Gui, Hide
RunWait, %ElonaExe%, %ElonaFolder%
GoSub InitData
Gui, Show
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Refresh data
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Refresh:
GoSub InitData
Return
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Exit program
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exit:
ExitApp