diff --git a/NNLocal.bas b/NNLocal.bas index 08fe790..04e8d64 100644 --- a/NNLocal.bas +++ b/NNLocal.bas @@ -46,7 +46,7 @@ sub local_gameplay end if empty_hand(0) end with - begin_local_game(0, 1) + begin_local_game(-1, 1) if LoadErrors then exit sub @@ -72,6 +72,7 @@ sub local_gameplay NewPlrSlot.Lives = StartingLives + (ExtraBarrierPoint * CampaignBarrier) InPassword = "--------" + SavedControls = ControlStyle do PlayerSlot(0).Difficulty = max(PlayerSlot(1).Difficulty,max(PlayerSlot(2).Difficulty,max(PlayerSlot(3).Difficulty,PlayerSlot(4).Difficulty))) @@ -245,7 +246,7 @@ sub local_gameplay end if with PlayerSlot(Player) - if DQ = 0 then + if DQ = 0 AND ControlStyle >= CTRL_DESKTOP then if .LevelNum > HighLevel AND .Lives > 0 then HighLevel = .LevelNum 'Clear victory flag; likely new levels discovered @@ -637,7 +638,7 @@ sub local_gameplay if TotalBC = 1 AND ContinuousSplit = 1 then force_release_balls - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 then for NewBall as short = 1 to 100 @@ -674,7 +675,37 @@ sub local_gameplay .Grabbed = .X .Y = 736 - PaddleHeight if GamePaused = 0 then - if ControlStyle <= CTRL_LAPTOP then + if ControlStyle = CTRL_AI then + dim as Basics Deepest + dim as short ObjsFound = 0 + Deepest.Y = 600.0 + Deepest.X = DesireX + + for BID as short = 1 to NumBalls + with Ball(BID) + if .Y > Deepest.Y AND .Y < 736 + BallSize AND sin(degtorad(.Angle)) < 0 then + Deepest.Y = .Y + Deepest.X = .X + ObjsFound += 1 + end if + end with + next BID + + for CID as short = 1 to MaxFallCaps + with Capsule(CID) + if .Y > Deepest.Y AND .Y < 736 AND .Angle <> CAP_SLOW AND .Angle <> CAP_NEGATER AND _ + .Angle <> CAP_SLOW_PAD AND .Angle <> CAP_WEAK AND .Angle <> CAP_GRAVITY then + Deepest.Y = .Y + Deepest.X = .X + ObjsFound += 1 + end if + end with + next CID + + if ObjsFound > 0 AND (abs(DesireX - Deepest.X) > PaddleSize/2 OR abs(DesireX - Deepest.X) < 1) then + DesireX = Deepest.X + irandom(-20,20) + end if + elseif ControlStyle <= CTRL_LAPTOP then Result = getmouse(MouseX,0,0,ButtonCombo) if Result = 0 then if .Reverse > 0 then @@ -1403,7 +1434,7 @@ sub local_gameplay end with next BID - if (InType = "p" OR DebugConsole OR e.type = EVENT_WINDOW_LOST_FOCUS) AND LevelClear = 0 then + if (InType = "p" OR DebugConsole OR (e.type = EVENT_WINDOW_LOST_FOCUS AND ControlStyle >= CTRL_DESKTOP)) AND LevelClear = 0 then GamePaused = 1 end if elseif LevelClear > 0 then @@ -1699,7 +1730,7 @@ sub local_gameplay FreezeStr = (FreezeStr + 60) / 2 Instructions = "Blizzard granted" elseif DebugCode = "CURVEDOWN" then - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power <> -2 then .Gravity = 900 @@ -1725,7 +1756,7 @@ sub local_gameplay case 3 reset_paddle(1) case 4 - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 then .Power = -1 @@ -1749,7 +1780,7 @@ sub local_gameplay end if with Paddle(1) - if ControlStyle <= CTRL_LAPTOP then + if ControlStyle >= CTRL_DESKTOP AND ControlStyle <= CTRL_LAPTOP then if .Reverse > 0 then setmouse(1024-.X,240,0,1) else @@ -1777,7 +1808,7 @@ sub local_gameplay end if if InType = "p" AND DebugConsole = 0 then - if ControlStyle <= CTRL_LAPTOP then + if ControlStyle >= CTRL_DESKTOP AND ControlStyle <= CTRL_LAPTOP then with Paddle(1) if .Reverse > 0 then setmouse(1024-.X,240,0,1) @@ -1823,7 +1854,7 @@ sub local_gameplay select case .Angle case CAP_SLOW capsule_message("SLOWER BALLS: All ball speeds slowed to minimum") - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power <> -2 then .Speed = MinSpeed @@ -1834,7 +1865,7 @@ sub local_gameplay play_clip(SFX_POWER_UP,.X) case CAP_FAST capsule_message("FASTER BALLS") - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power <> -2 then adjust_speed(BID,min(4,int(ActiveDifficulty+0.5))) @@ -1888,7 +1919,7 @@ sub local_gameplay force_release_balls RollBall = irandom(1,TotalBC) - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power <> -2 then BallsFound += 1 @@ -1926,7 +1957,7 @@ sub local_gameplay dim as ubyte Splitted(NumBalls) capsule_message("SPLIT BALL") force_release_balls - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND Splitted(BID) = 0 AND .Power <> -2 then for NewBall as short = 1 to 100 @@ -2014,7 +2045,7 @@ sub local_gameplay dim as ubyte TotalNew = 0, Splitted(NumBalls) capsule_message("MYSTERY CAPSULE: Quad Split",1) force_release_balls - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND Splitted(BID) = 0 AND .Power <> -2 then TotalNew = 0 @@ -2053,7 +2084,7 @@ sub local_gameplay play_clip(SFX_POWER_UP,.X) elseif Effects < .8 AND (Gamestyle AND (1 SHL STYLE_BOSS)) = 0 then capsule_message("MYSTERY CAPSULE: Lightning Balls (Fire/Breakthru combined)",1) - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power >= -1 then .Power = 4 @@ -2068,7 +2099,7 @@ sub local_gameplay capsule_message("MYSTERY CAPSULE: Split Deluxe",1) force_release_balls ContinuousSplit = 1 - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND Splitted(BID) = 0 AND .Power <> -2 then for NewBall as short = 1 to 100 @@ -2109,7 +2140,7 @@ sub local_gameplay case CAP_EXTENDER dim as byte ExtraLen = 15 capsule_message("EFFECT EXTENDER: Timed effects last 0:"+str(ExtraLen)+" longer") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Duration > 0 AND .Power > -2 then .Duration += ExtraLen*60 @@ -2139,7 +2170,7 @@ sub local_gameplay play_clip(SFX_POWER_UP,.X) case CAP_NEGATER capsule_message("EFFECT NEGATER: Timed effects ended early") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Power > -2 then .Duration = 0 @@ -2159,7 +2190,7 @@ sub local_gameplay play_clip(SFX_POWER_DOWN,.X) case CAP_WEAK capsule_message("WEAKENED BALLS: Ball damage is temporarily inconsistent") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Power <> -2 then if .Power <= 0 then @@ -2175,7 +2206,7 @@ sub local_gameplay play_clip(SFX_POWER_DOWN,.X) case CAP_FIRE capsule_message("FIRE BALLS: Explosive damage") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Power <> -2 then if .Power = 2 then @@ -2197,7 +2228,7 @@ sub local_gameplay play_clip(SFX_POWER_UP,.X) case CAP_THRU capsule_message("BREAKTHRU BALLS: Balls do not bounce off of bricks") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Power <> -2 then if .Power = 3 then @@ -2219,7 +2250,7 @@ sub local_gameplay play_clip(SFX_POWER_UP,.X) case CAP_GRAVITY capsule_message("GRAVITY BALLS: Balls temporarily curve towards the paddle") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Power <> -2 then .Gravity = max(.Gravity,900) @@ -2230,7 +2261,7 @@ sub local_gameplay play_clip(SFX_POWER_DOWN,.X) case CAP_MAXIMIZE capsule_message("MAXIMUM BALL SPEED!!! Brace yourself!") - for FID as ubyte = 1 to NumBalls + for FID as short = 1 to NumBalls with Ball(FID) if .Speed > 0 AND .Power <> -2 then .Speed = min(max(BaseMaxSpeed,.Speed + 2),BaseMaxSpeed + 2) @@ -2463,10 +2494,10 @@ sub local_gameplay end if if InPassword <> "--------" then - Instructions = "Password: "+InPassword+" (Push 1-4 when done)" + Instructions = "Password: "+InPassword+" (Push 0-4 when done)" InstructExpire = timer + 1 - for PID as ubyte = 1 to 4 + for PID as ubyte = 0 to 4 if InType = str(PID) then NumPlayers = PID PassInput = 1 @@ -2496,7 +2527,7 @@ sub local_gameplay end if else for HID as ubyte = 0 to NumHints - GameHints(HID) = abs(sgn(HintLevel < 3)) * 9 + GameHints(HID) = abs(sgn(HintLevel < 3)) * 8 next HID if NumPlayers > 1 then MPAlternate += 1 @@ -2509,7 +2540,7 @@ sub local_gameplay if PlayerSlot(0).Difficulty < 6.5 AND ShuffleLevels = 0 AND CampaignFolder <> EndlessFolder AND CampaignName <> PlaytestName AND Phase <> 0 then Instructions = "Push F4 to open the level screen" else - Instructions = "Push 1-4 to start a new campaign with that many players" + Instructions = "Push 0-4 to start a new campaign with that many players" end if InstructExpire = timer + 1 end if @@ -2527,14 +2558,14 @@ sub local_gameplay Instructions = "When three breakable blocks remain, a warp timer starts" InstructExpire = timer + 10 GameHints(4) = 1 - elseif TotalBC > 0 then + elseif TotalBC > 0 AND GameHints(0) < 1 then GameHints(0) = 1 end if if CampaignBarrier then if AboveLine = 0 AND TotalBC > 0 AND BarrierStrength > 0 AND GamePaused = 0 then with PlayerSlot(Player) - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if .Speed > 0 AND .Power >= -1 then .Angle = -.Angle @@ -2588,7 +2619,7 @@ sub local_gameplay end with else 'Kill off any balls that did not make their way back - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls with Ball(BID) if sin(degtorad(.Angle)) < 0 AND .Speed > 0 AND .Y > 768 + BallSize then .X = 320 @@ -2614,6 +2645,8 @@ sub local_gameplay if GameHints(0) = 0 then GameHints(0) = 1 select case ControlStyle + case CTRL_AI + Instructions = "The computer will automatically play this game" case CTRL_DESKTOP Instructions = "Perform [ACTION] (Click) to release a ball" case CTRL_LAPTOP, CTRL_KEYBOARD @@ -2628,6 +2661,10 @@ sub local_gameplay end if end select InstructExpire = timer + 10 + elseif GameHints(0) < 9 AND ControlStyle = CTRL_AI then + GameHints(0) = 9 + Instructions = "Fair warning; the computer will neither give you stars nor new passwords!" + InstructExpire = timer + 10 elseif GameHints(4) = 1 AND PlayerSlot(Player).WarpTimer < 3540 then Instructions = "The level is considered cleared once time expires" InstructExpire = timer + 10 @@ -2677,7 +2714,7 @@ sub local_gameplay while timer < FrameTime + 1/60:sleep 1:wend InType = inkey if total_lives = 0 then - for PID as ubyte = 1 to 4 + for PID as ubyte = 0 to 4 if InType = str(PID) AND InPassword = "--------" then begin_local_game(PID, 1) @@ -2686,7 +2723,7 @@ sub local_gameplay end if next PID - elseif actionButton AND ProhibitSpawn = 0 then + elseif (ControlStyle = CTRL_AI OR actionButton) AND ProhibitSpawn = 0 then with Ball(1) if ActiveDifficulty >= 3.5 then .Speed = DefaultSpeed - irandom(0,30) / 100 @@ -2736,7 +2773,9 @@ sub local_gameplay end if if LevelClear >= LevelClearDelay AND actionButton then - setmouse(,,0,1) + if ControlStyle >= CTRL_DESKTOP then + setmouse(,,0,1) + end if LevelClear = 0 dim as ubyte InPlay @@ -2752,7 +2791,7 @@ sub local_gameplay ProhibitSpawn = 0 LevelDesc = 0 - for BID as ubyte = 1 to NumBalls + for BID as short = 1 to NumBalls if Ball(BID).Speed > 0 then InPlay = 1 exit for @@ -2763,12 +2802,14 @@ sub local_gameplay if .LevelNum >= SecretLevels AND HighLevel < SecretLevels AND SecretLevels > 0 then play_clip(SFX_EXPLODE) if DQ = 0 then - TotalXP += int(.Score * .Difficulty) high_score_input(Player) - if FileExists(CampaignName+".flag") = 0 then - 'Intentionally empty victory file - open CampaignName+".flag" for output as #21 - close #21 + if ControlStyle >= CTRL_DESKTOP then + TotalXP += int(.Score * .Difficulty) + if FileExists(CampaignName+".flag") = 0 then + 'Intentionally empty victory file + open CampaignName+".flag" for output as #21 + close #21 + end if end if end if empty_hand(Player) @@ -2789,12 +2830,14 @@ sub local_gameplay else play_clip(SFX_LIFE) if DQ = 0 then - TotalXP += int(.Score * .Difficulty * 2) high_score_input(Player) - if FileExists(CampaignName+".flag") = 0 then - 'Just like before, only this is for a true victory - open CampaignName+".flag" for output as #21 - close #21 + if ControlStyle >= CTRL_DESKTOP then + TotalXP += int(.Score * .Difficulty * 2) + if FileExists(CampaignName+".flag") = 0 then + 'Just like before, only this is for a true victory + open CampaignName+".flag" for output as #21 + close #21 + end if end if end if empty_hand(Player) @@ -2851,6 +2894,7 @@ sub local_gameplay close #2 end if end if + ControlStyle = SavedControls kill("Stats.dat") if InType = XBox then clean_up diff --git a/NNLocal.bi b/NNLocal.bi index e952147..2fb7502 100644 --- a/NNLocal.bi +++ b/NNLocal.bi @@ -1112,7 +1112,15 @@ sub generate_capsule(InX as byte, InY as byte, Explode as ubyte = 0) end if with PlayerSlot(Player) - if ActiveDifficulty < 1.5 OR ActiveDifficulty >= 10.5 then + if ControlStyle = CTRL_AI then + CapWeight(CAP_GRAB) = 0 + CapWeight(CAP_BLIZZARD) = 0 + CapWeight(CAP_MAXIMIZE) = 4 + CapWeight(CAP_GRAVITY) = 4 + CapWeight(CAP_SLOW_PAD) = 4 + CapWeight(CAP_NEGATER) = 2 + CapWeight(CAP_REVERSE) = 0 + elseif (ActiveDifficulty < 1.5 OR ActiveDifficulty >= 10.5) then CapWeight(CAP_FAST) = 0 CapWeight(CAP_WEAK) = 0 CapWeight(CAP_MAXIMIZE) = 0 @@ -1310,8 +1318,8 @@ sub auxillary_view(ByRef TextAlpha as short, ByRef TextBeta as short) end if DynamicString = space(2)+_ - left(.Namee,20)+space(max(20-len(.Namee),0))+_ - space(12-len(commaSep(.RawScore)))+commaSep(.RawScore)+_ + left(.Namee,len(AIName))+space(max(len(AIName)-len(.Namee),0))+_ + space(32-len(AIName)-len(commaSep(.RawScore)))+commaSep(.RawScore)+_ space(9-len(DispLevel))+DispLevel+_ space(7-len(DispDiff))+DispDiff+_ space(11-len(DispWeight))+DispWeight @@ -1402,7 +1410,9 @@ sub high_score_input(PlayerNum as byte, Automatic as byte = 0) end if if NewPosition <= SavedHighSlots then - if Automatic = 0 then + if ControlStyle = CTRL_AI then + NewName = AIName + elseif Automatic = 0 then do screenevent(@e) line(302,349)-(721,449),rgb(0,0,0),bf @@ -1430,13 +1440,17 @@ sub high_score_input(PlayerNum as byte, Automatic as byte = 0) InType = inkey screencopy - if (InType >= "A" AND InType <= "Z") OR (InType >= "a" AND InType <= "z") OR (InType >= "0" AND InType <= "9") then + if (InType >= "A" AND InType <= "Z") OR (InType >= "a" AND InType <= "z") OR (InType >= "0" AND InType <= "9") OR InType = space(1) then NewName += InType elseif InType = Backspace then NewName = left(NewName,len(NewName)-1) end if loop until InType = chr(13) InType = chr(255) + + if lcase(NewName) = lcase(AIName) then + NewName = DummyName + end if end if if NewName = "" then NewName = "Anonymous" @@ -1704,7 +1718,9 @@ sub shuffle_levels end sub sub begin_local_game(InitPlayers as byte, InitLevel as short) - setmouse(,,0,1) + if InitPlayers > 0 then + setmouse(,,0,1) + end if DQ = 0 Player = 1 @@ -1719,7 +1735,13 @@ sub begin_local_game(InitPlayers as byte, InitLevel as short) HighScore(HID).NewEntry = 0 next HID - if InitPlayers > 0 then + if InitPlayers >= 0 then + if InitPlayers > 0 then + ControlStyle = SavedControls + else + ControlStyle = CTRL_AI + end if + if InitLevel = 1 then shuffle_levels @@ -1743,7 +1765,7 @@ sub begin_local_game(InitPlayers as byte, InitLevel as short) PlayerSlot(PDID) = NewPlrSlot PlayerSlot(PDID).Difficulty = DifficultyRAM(PDID) fresh_level(PDID) - if PDID > InitPlayers then + if PDID > InitPlayers AND (PDID <> 1 OR InitPlayers < 0) then PlayerSlot(PDID).Lives = 0 end if next PDID diff --git a/Nebunoid.bas b/Nebunoid.bas index 1cad76f..a71fe36 100644 --- a/Nebunoid.bas +++ b/Nebunoid.bas @@ -36,7 +36,7 @@ if ScreenCreated = 0 OR FileExists("FS.ini") then bload(MasterDir+"/gfx/banner.bmp",TitleBanner) end if end if -windowtitle "Nebunoid 1.11" +windowtitle "Nebunoid 1.12" 'Foreground assets load_brick_gfx(MasterDir+"/gfx/blocks/") @@ -144,6 +144,7 @@ if FileExists("conf.ini") then input #10, EnhancedGFX case "controls" input #10, ControlStyle + ControlStyle = max(ControlStyle,CTRL_DESKTOP) case "campbarr" input #10, CampaignBarrier case "shuffle" @@ -373,7 +374,7 @@ do sleep 10 InType = inkey loop until InType = EscapeKey OR InType = XBox -if ControlStyle >= CTRL_KEYBOARD then +if ControlStyle < CTRL_DESKTOP OR ControlStyle >= CTRL_KEYBOARD then ControlStyle = CTRL_DESKTOP end if save_unlocks diff --git a/Nebunoid.bi b/Nebunoid.bi index e742c58..95acf82 100644 --- a/Nebunoid.bi +++ b/Nebunoid.bi @@ -7,6 +7,9 @@ declare sub local_gameplay const PlaytestName = "Quick Playtest Level" const EndlessFolder = "official/endless" +const AIName = "Nebunoid Intelligence" +const DummyName = "Pumpkin Eater" + 'Speed range specs const DefaultSpeed = 8 const MinSpeed = 6 @@ -130,7 +133,8 @@ enum CapsuleDesigns end enum enum ControlTypes - CTRL_DESKTOP = 0 + CTRL_AI = -1 + CTRL_DESKTOP CTRL_LAPTOP CTRL_TABLET CTRL_KEYBOARD @@ -272,8 +276,7 @@ dim shared as HighSlot HighScore(TotalHighSlots) dim shared as uinteger MouseX, MouseY, MouseColor, ButtonCombo, TotalXP, TotalStars dim shared as uinteger GameStyle, TourneyStyle, TourneyScore, ShotIndex -dim shared as ubyte Fullscreen, JoyAnalog, JoyInvertAxes, ControlStyle, TapWindow, CondensedLevel, _ - AllowHandicap, ShuffleLevels +dim shared as ubyte Fullscreen, JoyAnalog, JoyInvertAxes, TapWindow, CondensedLevel, AllowHandicap, ShuffleLevels dim shared as integer LastActive, Result, OrigX(1), DesireX, JoyButtonCombo, ExplodingValue, BGBrightness dim shared as single JoyAxis(7) dim shared as short TotalBC, FrameSkip, PaddleCycle, ExplodeCycle, KeyboardSpeed, JoyKeySetting, ProgressiveBounces, BlockBrushes @@ -287,7 +290,7 @@ dim shared as ParticleSpecs Particles(Particount) dim shared as ubyte DQ, Player, NumPlayers, DispLives, Invis, GfxStyle, ExploTick, _ BallSize, MenuMode, HoldClick, HoldAction -dim shared as byte EnhancedGFX, GamePaused, TourneyValid, TotalMessages, TotalUnread +dim shared as byte EnhancedGFX, GamePaused, TourneyValid, TotalMessages, TotalUnread, ControlStyle, SavedControls dim shared as any ptr BulletPic, MissilePic, CapsulePic(26), CapsuleBar(5), CapsuleBarFrame, PokerBar(5), Background, PaddlePic, _ SoftBrickPic, MultihitPic, InvinciblePic, ExplodePic, BaseExplode, SoftBrickConnL, SoftBrickConnR, SoftBrickConnT, SoftBrickConnB, _ MultihitConnL, MultihitConnR, MultihitConnT, MultihitConnB, InvincibleConnL, InvincibleConnR, InvincibleConnT, InvincibleConnB, _ @@ -375,6 +378,7 @@ sub read_campaigns(StarsOnly as ubyte = 0) .Folder = "official/fusion" .Difficulty = "Medium to Hard" .SetSize = 20 + .StarsToUnlock = 15 case 8 .Namee = "Challenge Campaign" .Folder = "official/challenge" @@ -1385,6 +1389,8 @@ end sub function actionButton(HoldCheck as byte = 0) as integer if HoldAction = 0 OR HoldCheck > 0 then select case ControlStyle + case CTRL_AI + return -1 case CTRL_DESKTOP return ButtonCombo case CTRL_LAPTOP, CTRL_KEYBOARD @@ -1401,4 +1407,6 @@ function actionButton(HoldCheck as byte = 0) as integer end if end select end if + + return (ControlStyle = CTRL_AI) end function diff --git a/manual.md b/manual.md index 981c76e..955aff1 100644 --- a/manual.md +++ b/manual.md @@ -10,6 +10,9 @@ Some blocks may *explode* upon contact, destroying themselves and adjacent block As soon as all of the scorable blocks are *eliminated* (from a regular ball's perspective), the level is cleared, bonuses are awarded, and a new level begins. The process repeats until either every life is exhausted (although a continue may be used to gain more lives), or until the campaign has been completed. +#### Auto Play +Nebunoid supports watching an Auto Play session; just start a *0* player session. Fair warning; the computer player will neither give stars, nor award passwords for levels that the player has never played before. Any high scores it is able to submit will be auto-named as such. + ### Difficulty Levels Nebunoid supports a difficulty scale for *each* player, allowing players of varying skill to participate.