Post subject: New emulator-based art form?
Active player (324)
Joined: 2/23/2005
Posts: 786
I had this thought just now while contemplating the possibilities of Lua. If Lua had a few specific features, it could possibly spawn a brand new form of enjoying emulated games. The features would have to be: the ability to load a save state by file name, and optionally, the ability to load a rom by file name. This would allow the possibility of creating "challenge scripts" that drop you at one point via a save state, watch RAM values to see when you accomplished the challenge and keep score or track of time, then drop you at the next challenge when the current one is over. So, imagine something like a Zelda 2 Boss rush that will cycle through all 7 bosses, then show you a scoreboard of how much damage you took and how much time you took, as the script kept track of the RAM values. Or how about beating the final boss of Zelda 2, then having it drop you into, say, the final boss of Mario 3. A "final boss rush" across multiple games could be created, for example. Then, there could be the possibility of creating hacked savestates, or lua scripts that modify ram values, that offer even more unique and unusual challenges. So... yeah. Any thoughts?
Post subject: Re: New emulator-based art form?
Joined: 2/1/2008
Posts: 347
CtrlAltDestroy wrote:
Or how about beating the final boss of Zelda 2, then having it drop you into, say, the final boss of Mario 3. A "final boss rush" across multiple games could be created, for example.
Sounds a whole lot like those special competitions that Nintendo put out back when the SNES was their top product where you would compete with others in several parts of random best-selling games using those special cartridges. Except, of course, this scripting thing would be one player instead of multi-player races against the game timer. Overall, this sounds like something I would like to check out if it ever becomes possible!
<ccfreak2k> There is no 'ctrl' button on DeHackEd's computer. DeHackEd is always in control.
Post subject: Re: New emulator-based art form?
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
CtrlAltDestroy wrote:
The features would have to be: the ability to load a save state by file name
Doesn't something like Savestate.load(File.open('gruu.sav', 'r').read()) and conversely, File.open('gruu.sav', 'w').write(Savestate.save()), work in LUA?
Skilled player (1636)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
That was easy. EDIT - Now properly displays time. Pause no longer counts toward final time. My best [URL=http://imageshack.us][/URL]
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Post subject: Re: New emulator-based art form?
Banned User, Former player
Joined: 12/23/2004
Posts: 1850
CtrlAltDestroy wrote:
I had this thought just now while contemplating the possibilities of Lua.
I had the idea first (and the scripting to prove it, heh... probably from around a month ago or so), but yeah, it's an interesting idea. I've just not acted on it beyond getting some basics, as I could never completely plan out how I wanted to do it, unfortunately.
Perma-banned
Skilled player (1636)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Since my last bit of code was so loved, I figured I give my fans another piece of code. DarkKobold's fan club: *chirp*, *chirp* This uses the same save states as the other. This time, it is a survival type game, see how many bosses you can kill before you die - with diminishing health bonuses for each boss killed.
local frame_count = 0;
local boss_count = 0;
local game_over = true;
local HP = 156;
local win = 0;

Boss = {'Needle Man', 'Magnet Man', 'Gemini Man', 'Hard Man', 'Top Man', 'Snake Man',  'Spark Man', 'Shadow Man'};

bord = {};
bordc = 1;
a = savestate.create(10);
b = savestate.create(1);
c = savestate.create(2);
d = savestate.create(3);
e = savestate.create(4);
f = savestate.create(5);
g = savestate.create(6);
h = savestate.create(7);
i = savestate.create(8);

Snake = 0xA8;
Beam = 0xA3;
Needle = 0xA4;
Knuck = 0xA5;
Top = 0xA7;
Spark = 0xAA;
Blade =0xAC;
Magnet = 0xA6;

Life_Gain = 15;
Reserve = 0;
min = 0;
sec = 0;
fr = 0;

local Snakes =156;
local Beams =156;
local Needles = 156;
local Tops = 156;
local Sparks = 156;
local Blades = 156;
local Knucks = 156;
local Magnets = 156;


while (game_over) do 
	for z=1,fr+1,1 do
		choice = math.random(0,7);
	end;
	if (choice == 0x00) then
		savestate.load(b);
	elseif (choice== 0x01) then
		savestate.load(c);
	elseif (choice == 0x02) then
		savestate.load(d);
	elseif (choice == 0x03) then
		savestate.load(e);
	elseif (choice == 0x04) then
		savestate.load(f);
	elseif (choice == 0x05) then
		savestate.load(g);
	elseif (choice == 0x06) then
		savestate.load(h);
	elseif (choice == 0x07) then
		savestate.load(i);
	end;
	memory.writebyte(0xA2, HP);
	memory.writebyte(Snake,Snakes);
	memory.writebyte(Top,Tops);
	memory.writebyte(Knuck,Knucks);
	memory.writebyte(Magnet,Magnets);
	memory.writebyte(Beam,Beams);
	memory.writebyte(Blade,Blades);
	memory.writebyte(Spark,Sparks);
	memory.writebyte(Needle,Needles);
	memory.writebyte(0xAE,0);
	memory.writebyte(0xAF,0);
	memory.writebyte(0xA9,0);
	memory.writebyte(0xAB,0);
	memory.writebyte(0xAD,0);
for z = 0,150,1 do 

	    gui.text(50,10,"Time: " .. min.. ":" .. string.format('%02d',sec) .. "." .. string.format('%02d',fr));
	    gui.text(50,20, "Boss Count: "..bordc-1);
			FCEU.frameadvance();
	        end;
	while ((memory.readbyte(0xA2) > 0x80) and (memory.readbyte(0xB0) > 0x80)) do
	    min = math.floor(frame_count/3600);
	    sec = math.floor((frame_count-min*3600)/60);
	    fr = frame_count-min*3600-sec*60;
	    gui.text(50,10,"Time: " .. min.. ":" .. string.format('%02d',sec) .. "." .. string.format('%02d',fr));
	    gui.text(50,20, "Boss Count: "..bordc-1);
	    FCEU.frameadvance();
	    if (memory.readbyte(0x78) == 0) then 
	   	    frame_count = frame_count + 1;
	   end; 


	end;



	if (memory.readbyte(0xA2) < 0x81) then
		game_over = false;
	end;




	if (memory.readbyte(0xB0) < 0x81) then
		HP = memory.readbyte(0xA2) + Life_Gain + Reserve;
		Reserve = math.max(0,HP-156);
		for z = 0,400,1 do 
			FCEU.frameadvance();

	    gui.text(80,120,"Time: " .. min.. ":" .. string.format('%02d',sec) .. "." .. string.format('%02d',fr));
	    gui.text(80,130, "Boss Count: "..bordc);
	    gui.text(80,140, "Life Bonus: +" ..Life_Gain);
	    gui.text(80,150, "Current Reserve: "..Reserve);
	    	    
	        end;
		HP = math.min(156,HP);
		Life_Gain = Life_Gain - 1;

		if (Life_Gain < 0) then
		  Life_Gain = 0;
		end;

		
	
		Needles = memory.readbyte(Needle);
		Beams = memory.readbyte(Beam);
		Blades = memory.readbyte(Blade);
		Sparks = memory.readbyte(Spark);
		Knucks = memory.readbyte(Knuck);
		Magnets = memory.readbyte(Magnet);
		Tops = memory.readbyte(Top);
		Snakes = memory.readbyte(Snake);
		
		if (memory.readbyte(0x022) == 0x00) then
			bord[bordc] = 0;
		elseif (memory.readbyte(0x022) == 0x01) then
			bord[bordc] = 1;
		elseif (memory.readbyte(0x022) == 0x02) then
			bord[bordc] = 2;
		elseif (memory.readbyte(0x022) == 0x03) then
			bord[bordc] = 3;
		elseif (memory.readbyte(0x022) == 0x04) then
			bord[bordc] = 4;
		elseif (memory.readbyte(0x022) == 0x05) then
			bord[bordc] = 5;
		elseif (memory.readbyte(0x022) == 0x06) then
			bord[bordc] = 6;
		elseif (memory.readbyte(0x022) == 0x07) then
			bord[bordc] = 7;
		end;

		Blades = math.min(156,Blades+2);
		Magnets = math.min(156,Magnets+3);
		Beams = math.min(156,Beams+3);
		Sparks = math.min(156, Sparks+2);
		Knucks = math.min(156,Knucks+3);
		Tops = math.min(156,Tops+4);
		Snakes = math.min(156, Snakes+2);
		Needles = math.min(156, Needles + 2);
		bordc = bordc + 1;		
	end;

end;
	for z = 1,180,1 do
		gui.text(100,100, "GAME OVER");
	        FCEU.frameadvance();
	end;
	for z = 1,3000,1 do
	    min = math.floor(frame_count/3600);
	    sec = math.floor((frame_count-min*3600)/60);
	    fr = frame_count-min*3600-sec*60;
	    gui.text(30,10, "Game Over");
	    gui.text(30,20,"Survival Time: " .. min.. ":" .. string.format('%02d',sec) .. "." .. string.format('%02d',fr));
            gui.text(30,30,"Bosses Killed: "..  bordc-1);            
            x = 10;
	    y = 10;
		    for temp = 1,bordc-1,1 do
	        	    gui.text(x,30+y,temp.. ". " ..Boss[bord[temp]+1]);	
		            y = y+10;
			    if (y > 160) then
				x=x+81;
				y = 10;
			    end;
		    end;	
	    FCEU.frameadvance();
	end;


Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 4/25/2004
Posts: 498
All that happens when I run the script is that FCEUX crashes. :( Though I notice you're using 2.0.2 in the screenshot, and I'm using 2.0.3...dunno if that has anything to do with it.
Former player
Joined: 1/29/2007
Posts: 116
It worked fine with 2.0.2. I would not exactly call it art, but that sure was awesome! I suck at MM3 though, just made it through like 5 bosses. Very nice work that script! I certainly recommend everybody to try that out, and please, make more of the like ^^