Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save gareve/f1897ad0fa0d6090270cf5438c959230 to your computer and use it in GitHub Desktop.
Save gareve/f1897ad0fa0d6090270cf5438c959230 to your computer and use it in GitHub Desktop.
[Contra NES][Memory Inspection] Enemy HP Stats research for Difficulty/Loop Challenge
--[[
This script renders the enemy HP in screen + forces a difficulty/loop level
Made with the help of the followin apps & resources
bizhawk@Linux = monocomplete + libopenal1
Game Genius Addresses: https://gamehacking.org/game/29281
Contra Lua Sample Code: https://www.romhacking.net/games/137/
HP of enemies in final level
Loop lvl: 0 1 2 3 4 10 20 30 40 50 60 70 80 90 100
=======================================================================
mouths: 7 9 11 13 15 27 47 67 87 107 127 147 167 187 207
spiders: 5 6 7 8 9 15 25 35 45 55 65 75 85 95 105
eggs: 30 32 34 36 38 50 70 90 110 130 150 170 190 210 230
heart:103 119 135 151 160 160 160 160 160 135 160 160 103 160 160
alien head:103 119 135 151 160 160 160 160 160 135 160 160 103 160 160
]]
local enemy_state = {}
function game_loop()
-- Reading from disk file in realtime so I don't have to refresh the lua interpreter all the time
f = io.open('/home/someone/cuack.txt', 'r')
file_content = f:read()
f:close()
-- gui.text(50, 20, 'File: '.. file_content)
-- memory.writebyte(0x31, 70) -- Hardcode Difficulty
if file_content ~= nil then
memory.writebyte(0x31, tonumber(file_content)) -- Difficulty on file
end
local difficulty = memory.readbyte(0x31)
memory.writebyte(0xDA03, 0xA5) --Infinite Lives
memory.writebyte(0xD467, 0xB5) -- Invincible
memory.writebyte(0xDAD2, 0x03) -- Spread Gun after death
memory.writebyte(0x30, 0x07) --Jump to last level
-- -- memory.writebyte(0x07F8, 0)
gui.text(50, 50, 'Loop#: '.. difficulty, 'white', 'yellow')
local table = input.get()
if table.G then
gui.text(50, 80, 'G')
-- memory.write_u16_le(0xD04D, 0x3B) -- Pass level on START
end
if table.B then
gui.text(50, 90, 'B')
-- memory.writebyte(0x31, difficulty + 1)
enemy_state = {} -- clear table of enemy states
end
for i = 0,0xf do -- iterating through all possible enemies
local ENEMY_X_POS = memory.readbyte(0x033e + i)
local ENEMY_Y_POS = memory.readbyte(0x0324 + i)
local ENEMY_HP = memory.readbyte(0x0578 + i)
if ENEMY_HP ~= 240 and ENEMY_HP ~= 0 then
if enemy_state[i] == nil or ENEMY_HP > enemy_state[i] then
enemy_state[i] = ENEMY_HP -- best effort way to guess max health
end
gui.text(ENEMY_X_POS*3.1, ENEMY_Y_POS*3.1, string.format("%d/%d", ENEMY_HP, enemy_state[i]))
else
enemy_state[i] = nil
end
end
end
event.onframestart(game_loop)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment