1 2 3
13 14
Masterjun
He/Him
Site Developer, Skilled player (1970)
Joined: 10/12/2010
Posts: 1179
Location: Germany
In Lua, the number 0x1234 is the same as the number 4660. (You can see that by trying out print(0x1234), it will print 4660 in the console) tl;dr Both
Warning: Might glitch to credits I will finish this ACE soon as possible (or will I?)
Editor, Player (53)
Joined: 12/25/2004
Posts: 634
Location: Aguascalientes, Mexico
It accepts integer numbers, is just that is common to input them in hexadecimal, but you can simple put its decimal form. http://tasvideos.org/Bizhawk/LuaFunctions.html
I'm the best in the Universe! Remember that!
Pokota
He/Him
Joined: 2/5/2014
Posts: 779
Alright, new lua HUD time - this time for Metroid II: Return of Samus. EDIT: On second thought, look two posts down.
Adventures in Lua When did I get a vest?
Site Admin, Skilled player (1236)
Joined: 4/17/2010
Posts: 11268
Location: RU
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Pokota
He/Him
Joined: 2/5/2014
Posts: 779
I just have to remember to call the selector from the right table - I kept bumping into bugs where I was calling the entire table instead of the value at i Also updated script below:
Language: lua

--[[ General scripts for Metroid II: Return of Samus for Gameboy/GB ]] enemy = {"indicator","health","maxhealth","frozen","lifeperc","isdrop","isupgrade"} enemy.indicator = {} enemy.health = {} enemy.maxhealth = {} enemy.frozen = {} enemy.lifeperc = {} enemy.isdrop = {} enemy.isupgrade = {} samus = {"basehp","maxhp","perchp"} bombs = { } bombperc = { } ubite = memory.read_u8 sbite = memory.read_s8 circ = gui.drawPie rekt = gui.drawRectangle bawx = gui.drawBox function core() getSamusLife() getEnemyStats() updateBombTimers() calcPercents() drawBombTimers() drawHealthBars() end function getSamusLife() za = ubite(0x1051) upda = string.format("%2x",za) za = tonumber(upda,10) zb = ubite(0x1050) zc = ubite(0x1052) samus.maxhp = 99 + (zb*99) samus.basehp = za + (zc*99) end function getEnemyStats() root = 0x0600 for i = 0,7 do enemy.indicator[i] = root + i*32 enemy.health[i] = ubite(enemy.indicator[i] + 12) enemy.maxhealth[i] = ubite(enemy.indicator[i] + 17) enemy.frozen[i] = ubite(enemy.indicator[i] + 11) enemy.isdrop[i] = sbite(enemy.indicator[i] + 13) enemy.isupgrade[i] = ubite(enemy.indicator[i] + 4) enemy.indicator[i] = sbite(enemy.indicator[i]) if enemy.maxhealth[i] >= 250 then enemy.health[i] = 0 end if enemy.maxhealth[i] == 0 then enemy.maxhealth[i] = 1 enemy.health[i] = 0 end end end function updateBombTimers() bombs[1] = ubite(0x1d31) bombs[2] = ubite(0x1d41) bombs[3] = ubite(0x1d51) end function calcPercents() -- first, calc percents for the bombs since it's a simple loop with a bound check for i, v in ipairs(bombs) do if (bombs[i] ~= 255) then bombperc[i] = bombs[i] / 95 else bombperc[i] = 0 end end samus.perchp = samus.basehp / samus.maxhp for i = 0, 7 do enemy.lifeperc[i] = enemy.health[i] / enemy.maxhealth[i] end end function drawBombTimers() for i, v in ipairs(bombperc) do circ(i*10,8,8,8,-90,bombperc[i]*360,"Green","Green") end end function drawHealthBars() bawx(0,136,64,143,0xFF666666,0xFF666666) rekt(1,137,samus.perchp*62,5,0xFF333333,0xFF333333) for i = 0,7 do if (enemy.indicator[i] ~= -1) then -- Is the enemy slot active? if (enemy.isdrop[i] == 0) then -- Make sure it's not an item if (enemy.frozen[i] == 0) then -- If it's not frozen, use red rekt(150+i,0,1,100*enemy.lifeperc[i],0xFFFF0000,0xFFFF0000) else -- otherwise, use cyan rekt(150+i,0,1,100*enemy.lifeperc[i],0xFF00FFFF,0xFF00FFFF) end end end end end event.onframeend(core)
Still need to figure out how to handle doors and the spring ball enemy, but it no longer shows health bars for projectiles and Gamma Metroid barriers. EDIT: Removed one check since it was ultimately redundant. EDITWO: Added a sanity check to getEnemyStats()
Adventures in Lua When did I get a vest?
Post subject: BizHawk crashes when using Pokota Lua script
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
I tried the Pokota Lua script. I opened the game and went to the savestate right before the Metroid Queen (at the corridor with spikes). However, as soon as Samus descends into the boss lair, BizHawk crashes with this message:
LuaInterface.LuaScriptException: [string "main"]:107: A .NET exception occured in user-code
Inner Exception:
System.OverflowException: Overflow error.
   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
   at System.Drawing.Graphics.FillRectangle(Brush brush, Int32 x, Int32 y, Int32 width, Int32 height)
   at BizHawk.Client.EmuHawk.GuiLuaLibrary.DrawRectangle(Int32 x, Int32 y, Int32 width, Int32 height, Nullable`1 line, Nullable`1 background)
StackTrace:
   at LuaInterface.Lua.ThrowExceptionFromError(Int32 oldTop)
   at LuaInterface.Lua.callFunction(Object function, Object[] args, Type[] returnTypes)
   at LuaInterface.Lua.callFunction(Object function, Object[] args)
   at LuaInterface.LuaFunction.Call(Object[] args)
   at BizHawk.Client.Common.EventLuaLibrary.CallFrameAfterEvent()
   at BizHawk.Client.EmuHawk.MainForm.StepRunLoop_Core(Boolean force)
   at BizHawk.Client.EmuHawk.MainForm.ProgramRunLoop()
   at BizHawk.Client.EmuHawk.Program.SubMain(String[] args)
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Speaking as someone who doesn't program in .net, it probably uses invalid parameters for the function FillRectangle.
Editor, Skilled player (1939)
Joined: 6/15/2005
Posts: 3247
Two things with Pokota's Lua script: One is that any runtime error that occurs when using event.onframeend (as well as event.onframebegin; I tested that as well) crashes BizHawk 1.9.3 entirely. This also occurs in BizHawk 1.9.1 and 1.9.2. The crashes do not occur if done like this:
while true do
 core()
 emu.frameadvance()
end 
instead of using event.onframeend. In this case, the Lua console just displays the error. The other is that the script divides by 0 and uses that in gui.drawRectangle. This is a runtime error in BizHawk 1.9.2 and 1.9.3 (but not 1.9.1). If it is done with emu.frameadvance() as above, it gives the error message:
LuaInterface.LuaScriptException: 4294901760
Division by 0 itself is not a runtime error. The division by 0 occurs because of the following two lines:
samus.perchp = samus.basehp / samus.maxhp

enemy.lifeperc[i] = enemy.health[i] / enemy.maxhealth[i]
Pokota
He/Him
Joined: 2/5/2014
Posts: 779
It shouldn't be dividing by zero ever as there are no enemies with a max health of 0 (Oddly, items have a nonzero health value as well), but I'll take another look at how the data is stored during the Queen battle. If necessary I'll add in a sanity check during the byte scrapes to set max health to 1 if it's 0. The relevant range of bytes is from 0x0600 through 0x06FF; I've been monitoring the region via the hex editor function. It's really interesting to see what pops up there and what doesn't - an example is there is something in the Space Jump ruins' catacombs, where there's the alpha and gamma metroids in those rooms full of netting, near the cast off shell for the gamma.
Adventures in Lua When did I get a vest?
Editor, Skilled player (1939)
Joined: 6/15/2005
Posts: 3247
Pokota wrote:
It shouldn't be dividing by zero ever as there are no enemies with a max health of 0 (Oddly, items have a nonzero health value as well), but I'll take another look at how the data is stored during the Queen battle.
Games do weird things with memory sometimes so that it appears as if there are enemies with 0 max health (even if there aren't supposed to be enemies). I got the error just by doing a game over.
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
FractalFusion wrote:
Games do weird things with memory sometimes so that it appears as if there are enemies with 0 max health (even if there aren't supposed to be enemies).
The game code might be just reusing the same memory region for other data. For instance, the Game Over screen might run a completely unrelated chunk of code that just happens to use the same memory region. Anyway, checking for sane values before using them is always a good idea. :)
Post subject: SNES Push-Over Lua script
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
Push-Over, for SNES This script has the following features:
  • Level select.
  • Show the passcode for the current level.
  • Show the passcode using a sprite sheet image to draw the digits (instead of built-in text rendering). Requires latest SVN version; but the script also has a fallback code for text rendering.
  • Automatically takes screenshots of all levels. Since some levels take a bit longer to load, the script detects when the main character is at a specific animation frame, so he looks the same in all screenshots.
  • Bruteforce passcode testing. It will likely take 10 or 20 hours to bruteforce all passcodes (nope, I have not left it running for so long). Fun fact: for each passcode, the game also accepts the same passcode added by 2.
  • Since it is impossible to call emu.frameadvance() in a button handler function, this script implements a work around.
Language: lua

-- How to install: -- 1. Make sure the directory containing this lua script is writable. -- 2. Save the PNG image from the comment below into the same directory as the lua script. -- Must be placed in the same directory of the lua script. NUMBERS_PNG = "SNES_Push-Over_numbers.png" -- The contents of this image are: -- -- Will be saved at the same directory of the lua script. MAINMENU_SAVESTATE = "SNES_Push-Over_MainMenu.State" -- Some constants. PASSCODE_BASE = 0x001100 TIME_TICK = 0x000303 -- 1/50 of second TIME_SECOND = 0x000304 -- seconds -- Tables in Lua start counting from 1. -- Number literals starting with zero are still represented in base 10. PASSCODES = { 00512, -- Level 01 01536, -- Level 02 01024, -- Level 03 03072, -- Level 04 03584, -- Level 05 02560, -- Level 06 02048, -- Level 07 06144, -- Level 08 06656, -- Level 09 07680, -- Level 10 07168, -- Level 11 05122, -- Level 12 05634, -- Level 13 04610, -- Level 14 04098, -- Level 15 12290, -- Level 16 12802, -- Level 17 13826, -- Level 18 13314, -- Level 19 15362, -- Level 20 15878, -- Level 21 14854, -- Level 22 14342, -- Level 23 10246, -- Level 24 10758, -- Level 25 11782, -- Level 26 11270, -- Level 27 09222, -- Level 28 09734, -- Level 29 08718, -- Level 30 08206, -- Level 31 24590, -- Level 32 25102, -- Level 33 26126, -- Level 34 25614, -- Level 35 27662, -- Level 36 28174, -- Level 37 27150, -- Level 38 26638, -- Level 39 30734, -- Level 40 31246, -- Level 41 32270, -- Level 42 31758, -- Level 43 29726, -- Level 44 30238, -- Level 45 29214, -- Level 46 28702, -- Level 47 20510, -- Level 48 21022, -- Level 49 22046, -- Level 50 21534, -- Level 51 23582, -- Level 52 24094, -- Level 53 23070, -- Level 54 22558, -- Level 55 18494, -- Level 56 19006, -- Level 57 20030, -- Level 58 19518, -- Level 59 17470, -- Level 60 17982, -- Level 61 16958, -- Level 62 16510, -- Level 63 16511, -- Level 64 17023, -- Level 65 18047, -- Level 66 17535, -- Level 67 19583, -- Level 68 20095, -- Level 69 19071, -- Level 70 18559, -- Level 71 22655, -- Level 72 23167, -- Level 73 24191, -- Level 74 23679, -- Level 75 21631, -- Level 76 22143, -- Level 77 21247, -- Level 78 20735, -- Level 79 28927, -- Level 80 29439, -- Level 81 30463, -- Level 82 29951, -- Level 83 31999, -- Level 84 32511, -- Level 85 31487, -- Level 86 30975, -- Level 87 26879, -- Level 88 27647, -- Level 89 28671, -- Level 90 28159, -- Level 91 26111, -- Level 92 26623, -- Level 93 25599, -- Level 94 25087, -- Level 95 08703, -- Level 96 09215, -- Level 97 10239, -- Level 98 09727, -- Level 99 44543 -- Level 00? } function input_passcode(passcode) for index = 8, 0, -2 do local digit = passcode % 10 passcode = (passcode-digit) / 10 mainmemory.write_u16_le(PASSCODE_BASE + index, digit) end end function get_passcode_digit(index) return mainmemory.read_u16_le(PASSCODE_BASE + 2 * index) % 10 end function draw_passcode() for i = 0, 4, 1 do local value = get_passcode_digit(i) if gui.drawImageRegion then -- Implemented in BizHawk revision 9265, fixed a few revisions later. gui.drawImageRegion(NUMBERS_PNG, 0, value * 16, 16, 16, 128 - 40 + i * 16, -1) else gui.drawText(128 - 40 + i * 16, 0, value, 0xFFFFFFFF, 16) end end end -- joypad.set sets the value for a single frame function reset() joypad.set({Reset = true}) end function start() joypad.set({Start = true}, 1) end function wait_until(domain, address, byte_value) memory.usememorydomain(domain) while memory.readbyte(address) ~= byte_value do emu.frameadvance() end memory.usememorydomain("WRAM") end function wait_until_tick_equals_to(value) wait_until("WRAM", TIME_TICK, value) end function wait_main_character_is_getting_out() wait_until("VRAM", 0xC08A, 195) end function is_incorrect_code_screen() local BASE = 0x0022D0 local text = "incorrect code" for i = 1, 14, 1 do local ascii = string.byte(text, i) local value = mainmemory.readbyte(BASE + i*2) if ascii ~= 32 then -- Ignore space if value ~= ascii then return false end end end return true end function go_to_main_screen() reset() client.unpause() input_passcode(00000) client.speedmode(400) -- Waiting until the game resets to the passcode of the first level. -- wait_until("WRAM", PASSCODE_BASE + 4, 5) -- Waiting and auto-firing the Start button. while mainmemory.readbyte(PASSCODE_BASE + 4) ~= 5 do start() emu.frameadvance() emu.frameadvance() end -- Waiting one more frame to let the screen be drawn. emu.frameadvance() client.speedmode(100) savestate.save(MAINMENU_SAVESTATE) client.pause() end function go_to_level(level_number) savestate.load(MAINMENU_SAVESTATE) client.unpause() input_passcode(PASSCODES[level_number]) start() -- Setting the TICK to a known, arbitrary value. mainmemory.writebyte(TIME_TICK, 33) -- Waiting until it gets reset when the level starts. client.speedmode(400) wait_until_tick_equals_to(0) wait_main_character_is_getting_out() client.speedmode(100) client.pause() end function take_screenshots_of_all_levels() for level_number = 1, 100, 1 do go_to_level(level_number) -- Drawing the passcode at the top of the level. -- It is only captured in screenshots if "File->Screenshot->Capture OSD" is enabled. client.unpause() for i = 0, 32, 1 do -- Clearing OSD messages. gui.addmessage("") end if forms.ischecked(CHCK_SHOWPASSCODE) then draw_passcode() emu.frameadvance() end client.screenshot(string.format("Push-Over_level_%02d_passcode_%05d.png", level_number, PASSCODES[level_number])) end end function bruteforce_all_passcodes() client.speedmode(800) for passcode = 0, 99999, 1 do local passcode_string = string.format("%05d", passcode) savestate.load(MAINMENU_SAVESTATE) client.unpause() input_passcode(passcode) gui.addmessage(passcode_string) start() -- Setting the TICK to a known, arbitrary value. mainmemory.writebyte(TIME_TICK, 33) -- Waiting until it gets reset when the level starts. wait_until_tick_equals_to(0) if not is_incorrect_code_screen() then print(passcode_string) end end client.speedmode(100) client.pause() end -- GUI-related functions below. function button_mainmenu_click() SHOULD_GO_TO_LEVEL = -1 client.unpause() end function button_goToLevel_click() local level_number = forms.gettext(TEXT_LEVELNUM) level_number = tonumber(level_number) if level_number == nil then return; end level_number = math.floor(level_number) if level_number <= 0 or level_number > 100 then return; end SHOULD_GO_TO_LEVEL = level_number client.unpause() end function button_previousLevel_click() local level_number = forms.gettext(TEXT_LEVELNUM) forms.settext(TEXT_LEVELNUM, level_number - 1) button_goToLevel_click() end function button_nextLevel_click() local level_number = forms.gettext(TEXT_LEVELNUM) forms.settext(TEXT_LEVELNUM, level_number + 1) button_goToLevel_click() end function button_screenshots_click() SHOULD_GO_TO_LEVEL = -2 client.unpause() end function button_findpasscodes_click() SHOULD_GO_TO_LEVEL = -3 client.unpause() end FORM = forms.newform(128, 240, "Push-Over") BUTT_MAINMENU = forms.button(FORM, "Initialize Save State", button_mainmenu_click, 0, 0, 120, 20) LABL_LEVELNUM = forms.label(FORM, "Level:", 0, 30, 40, 20, false) TEXT_LEVELNUM = forms.textbox(FORM, "1", 40, 20, "UNSIGNED", 40, 30, false, true) BUTT_GOTOLEVEL = forms.button(FORM, "Go to level", button_goToLevel_click, 80, 30, 40, 20) BUTT_PREVLEVEL = forms.button(FORM, "< Prev", button_previousLevel_click, 0, 50, 60, 20) BUTT_NEXTLEVEL = forms.button(FORM, "Next >", button_nextLevel_click, 60, 50, 60, 20) CHCK_SHOWPASSCODE = forms.checkbox(FORM, "Show passcode", 0, 80) BUTT_SCREENSHOTS = forms.button(FORM, "Take screenshots of all levels", button_screenshots_click, 0, 110, 120, 40) BUTT_FINDPASSCODES = forms.button(FORM, "Bruteforce passcodes (very slow!)", button_findpasscodes_click, 0, 150, 120, 40) -- This is needed because we can't call emu.frameadvance from the GUI thread. SHOULD_GO_TO_LEVEL = nil while true do if SHOULD_GO_TO_LEVEL ~= nil then if SHOULD_GO_TO_LEVEL == -1 then go_to_main_screen() elseif SHOULD_GO_TO_LEVEL == -2 then take_screenshots_of_all_levels() elseif SHOULD_GO_TO_LEVEL == -3 then bruteforce_all_passcodes() elseif SHOULD_GO_TO_LEVEL > 0 and SHOULD_GO_TO_LEVEL <= 100 then go_to_level(SHOULD_GO_TO_LEVEL) end SHOULD_GO_TO_LEVEL = nil end if forms.ischecked(CHCK_SHOWPASSCODE) then draw_passcode() end emu.frameadvance() end
Moderators Note: The PNG Text Data was removed due to breaking the forums' layout. Please refrain from posting long single line strings.
AntyMew
It/Its
Encoder, Player (35)
Joined: 10/22/2014
Posts: 425
Is it just me or did that last post break the page? (line 9 of the script)
Just a Mew! 〜 It/She ΘΔ 〜
Editor
Joined: 3/31/2010
Posts: 1466
Location: Not playing Puyo Tetris
Anty-Lemon wrote:
Is it just me or did that last post break the page? (line 9 of the script)
It did
When TAS does Quake 1, SDA will declare war. The Prince doth arrive he doth please.
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
Once a moderator edits it, I cannot edit anymore. Anyway, here is the image, in case anyone wants:
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
you need to setup a source code repository somewhere
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
zeromus wrote:
you need to setup a source code repository somewhere
That's a nice idea, but I also like the idea of having a collaborative repository of lua scripts for BizHawk. What do you people think about it? A repository in GitHub (or somewhere else) where the community can keep the scripts. Kind of "next step" after this forum thread.
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
we have such a thing in the bizhawk repository, and we additionally like the idea of shipping them with bizhawk as a kind of standard library of perks, although this would need further evaluation if they began having 3rd party dll dependencies and big databases of images and such. There are probably several similar repositories elsewhere, but I dunno.
adelikat
He/Him
Emulator Coder, Site Developer, Site Owner, Expert player (3596)
Joined: 11/3/2004
Posts: 4738
Location: Tennessee
If there was a github repo, we could also move the "official" bizhawk lua scripts there, and we could pull from that repo as part of the release process
It's hard to look this good. My TAS projects
Pokota
He/Him
Joined: 2/5/2014
Posts: 779
Update time, Zelda II flavored. edit: updated code at bottom Right now the problem I'm having is that it won't draw the key graphic at all, regardless of if I'm trying to drawImage or drawIcon. The image file is in the same folder as the script, so I'm probably missing something obvious that I forgot. There should be two keys being drawn, and I can't see it if it is. EDIT: I think I fixed it but I'm not sure why this fixes it - for whatever reason it just fails at drawing images when you use event.onframestart(), but not when you use the old while true do loop method.
Language: lua

-- "Zelda II: The Adventure of Link" local bagCounter = 0 local currentMP = 0 local currentHP = 0 local maxMP = 0 local maxHP = 0 local hearts = 0 local jars = 0 local armor = 0 local intel = 0 local skill = 0 local xp = 0 local toLevel = 1 local percentToLevel = 1 local keys = 0 local selector = 0 local magic = {[0]="No Magic","Shield","Jump","Life","Fairy","Fire","Reflect","Spell","Thunder"} function main() bagCounter = memory.readbyte(0x05DF); currentMP = memory.readbyte(0x0773); currentHP = memory.readbyte(0x0774); hearts = memory.readbyte(0x0784); jars = memory.readbyte(0x0783); armor = memory.readbyte(0x0779); intel = memory.readbyte(0x0778); skill = memory.readbyte(0x0777); xp = (memory.readbyte(0x0775)*255)+memory.readbyte(0x0776); toLevel = (memory.readbyte(0x0770)*255)+memory.readbyte(0x0771); keys = memory.readbyte(0x0793); selector = memory.readbyte(0x0749) + 1; percentToLevel = xp / toLevel; maxMP = (jars*32)-1; maxHP = (hearts*32)-1; gui.drawBox(0,0,255,41,"White","Black"); gui.drawText(0,8,armor.."|HP: "..currentHP.."/"..maxHP,"Red",11); gui.drawText(0,18,intel.."|MP: "..currentMP.."/"..maxMP,"White",11); gui.drawText(0,28,skill.."|"..bagCounter.." enemies since last drop","Yellow",11); for i = 1, keys, 1 do gui.drawImage("key.png",95+(i*8),8); end gui.drawText(95,18,"Spell: "..magic[selector],"White",11); gui.drawRectangle(245,8,10,(32*percentToLevel),"Green","Green"); gui.drawBox(245,8,255,40,"White"); end while true do main() emu.frameadvance() end
editwo: For drawText, how do I fiddle with the font family - am I restricted to certain fonts or can I use any installed font?
Adventures in Lua When did I get a vest?
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
How do I use lua? Whenever I open the lua menu, it gives http://pastebin.com/wxGAm9RA If I drag the script instead if gave: http://imgur.com/BZlCN6M,iO9RRhP This happened with another user as well, but some managed it. What am I doing wrong?
Joined: 5/19/2015
Posts: 3
-deleting-
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
waterise wrote:
This Lua script provides me with a "Lua Console" that gives me output of the things that are happening in real-time within the game as it plays. Ok, now, Each output has a number next to it (the red square box in the pic in the console)...my question is: How can I take each output it gives me throughout the game and send that to my Twitch.tv Channel (via a chat bot)?
Suggestion: use the "forms" module create a new form window. In that window, add one or more labels. Then, instead of (or in addition to) printing to the console, you update the label text using settext(). Then, in your stream, you just capture this new window. If you want to see examples of using the forms module, look at one of my scripts (either from this thread, or from here), or maybe also some sample scripts shipped with BizHawk.
Site Admin, Skilled player (1236)
Joined: 4/17/2010
Posts: 11268
Location: RU
Suggestion: please do not embed 16000000x9000000 images into forum posts, just link to them.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Joined: 5/19/2015
Posts: 3
CrazyTerabyte wrote:
Suggestion: use the "forms" module create a new form window. In that window, add one or more labels. Then, instead of (or in addition to) printing to the console, you update the label text using settext(). Then, in your stream, you just capture this new window. If you want to see examples of using the forms module, look at one of my scripts (either from this thread, or from here), or maybe also some sample scripts shipped with BizHawk.
Thanks for that! But I can't do it that way. I need to use a Java bridge (the bot). Here's an example diagram: (link only because big picture) http://puu.sh/hT3H3.png For now, I can ignore the Twitter & LiveSplits part. My main focus is pushing BizHawk to the Java Bridge (which is a bot in my Channel, that I need to custom code apparently), then push that to the stream. I know I *need* a LuaSocket.
1 2 3
13 14