Forum rules - please read before posting.

Automated scene logic testing

edited October 2016 in Extending the editor
Testing your own adventure game where you know all the puzzles and every syllable of dialogue is beyond tedious, especially once you disable all the debugging shortcuts that you've (hopefully) put in there to save time and your own sanity during development.

Has anyone tried setting up an automated system for testing scene logic in an AC context? Something like what's being shown here: https://blog.thimbleweedpark.com/yay_testertron3000

If not, I think I'll give it a go myself this weekend, unless I gnaw through my wrists out of sheer boredom before then.

Wish I had the budget to hire these guys: https://youtu.be/BRWvfMLl4ho
«1

Comments

  • Thanks for the reminder - I really need to tighten up my graphics. :))
  • edited October 2016
    Yeah, they make it look so easy ....  :)

    Real-life professional testers are a special breed. I remember this one guy I used to work with (as a software developer you can work WITH or AGAINST your testers) - his job was to make my stuff crash, and he was famous for being able to break any piece of software within 30 seconds.

    I especially remember this one time when he managed to crash the whole system completely, literally minutes after we launched a new major version, and we suddenly had one of the vice presidents of the company visiting us code monkeys. When we went to see this particular tester demonstrate the problem, the conversation went something like this:

    VP: "But ... surely, no sane person would ever do that?"
    Tester: "Still makes it crash, doesn't it?"
    VP: "Hmmmm .... well done. Don't forget that with great power comes great responsibility!"

    I actually wrote a song back then about this guy called "At War With Software" - but that's a story for another day - let's break some adventure games in his spirit now! >:)
  • Got a system running now that moves the mouse pointer around randomly and clicks every now and then - it's fun to watch and might be useful for finding navigation problems.

    Next step is to make it aware of AC objects in the scene so it can be used for more structured testing.
  • Okay, here are the two scripts that enable random clicking and cursor movement in the game window in the editor.

    Windows only, I'm afraid.

    Put the RandomClicker on an empty gameobject in your scene and press ctrl-p to start and end the test (it will hijack your mouse cursor in Unity, but keep it inside the game window).

    The number of frames between clicks and cursor movement can be configured on the component.

    Use completely at your own risk!
  • RandomClicker.cs:

    using UnityEngine;

    public class RandomClicker : MonoBehaviour
    {
        public int ClickDelay = 30;
        public int MoveCursorDelay = 5;

        int clicker_countdown;
        int move_cursor_countdown;
        float x_offset;
        float y_offset;
        Vector2 game_window_size;

        void Awake()
        {
            DontDestroyOnLoad(transform.gameObject);
        }

        void Start ()
        {
    #if UNITY_EDITOR
            clicker_countdown = ClickDelay;
            move_cursor_countdown = MoveCursorDelay;
            game_window_size = UnityEditor.Handles.GetMainGameViewSize();
            MouseOperations.MousePoint point = MouseOperations.GetCursorPosition();
            x_offset = point.X - Input.mousePosition.x;
            y_offset = point.Y - Screen.height + Input.mousePosition.y;
        }

        void Update ()
        {
    #if UNITY_EDITOR
            if (move_cursor_countdown > 0) {
                move_cursor_countdown--;
            }
            else {
                MouseOperations.SetCursorPosition((int)(x_offset + Random.value * game_window_size.x),
                                                  (int)(y_offset + Random.value * game_window_size.y));
                move_cursor_countdown = MoveCursorDelay;
            }

            if (clicker_countdown > 0) {
                clicker_countdown--;
            }
            else {
                MouseOperations.MouseEvent(MouseOperations.MouseEventFlags.LeftUp | MouseOperations.MouseEventFlags.LeftDown);
                clicker_countdown = ClickDelay;
            }
        }
    }

  • MouseOperations.cs:

    using System;
    using System.Runtime.InteropServices;

    public class MouseOperations
    {
        [Flags]
        public enum MouseEventFlags
        {
            LeftDown = 0x00000002,
            LeftUp = 0x00000004,
            MiddleDown = 0x00000020,
            MiddleUp = 0x00000040,
            Move = 0x00000001,
            Absolute = 0x00008000,
            RightDown = 0x00000008,
            RightUp = 0x00000010
        }

        [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetCursorPos(int X, int Y);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetCursorPos(out MousePoint lpMousePoint);

        [DllImport("user32.dll")]
        private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

        public static void SetCursorPosition(int X, int Y)
        {
            SetCursorPos(X, Y);
        }

        public static void SetCursorPosition(MousePoint point)
        {
            SetCursorPos(point.X, point.Y);
        }

        public static MousePoint GetCursorPosition()
        {
            MousePoint currentMousePoint;
            var gotPoint = GetCursorPos(out currentMousePoint);
            if (!gotPoint) {
                currentMousePoint = new MousePoint(0, 0);
            }
            return currentMousePoint;
        }

        public static void MouseEvent(MouseEventFlags value)
        {
            MousePoint position = GetCursorPosition();
            mouse_event((int)value, position.X, position.Y, 0, 0);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MousePoint
        {
            public int X;
            public int Y;

            public MousePoint(int x, int y)
            {
                X = x;
                Y = y;
            }
        }
    }
  • Thinking about building on this to create a system for recording game sessions so they can be played back - could be really useful, especially if combined with a system for automatically checking the status of game objects at the end of the session ....
  • This is awesome!
    Although, I guess this is only really usable for Mouse-Only control schemes, right?

    I have a Walking Dead kind of control (WASD + Mouse) and this would really be a timesaver :D
  • Yes, at the moment it's mouse-only - because that's what I'm using for my own project - but I suppose it wouldn't be too hard to extend it to handle keyboard input as well. Will keep it in mind as I update it.
  • Awesome!
    Looking forward to it!
  • edited October 2016
    Quick demo in a somewhat empty scene:

    https://youtu.be/2U6QYpHuNws
  • I'm now adding to the logic so any visible hotspots are clicked at a configurable interval, instead of just clicking at a random position in the scene. This means the code is growing in size, so I'll create a Unity package for this and put it online very soon.

    Does the community wiki provide direct support for binary files, or should I put it in my public dropbox folder and just provide a link on the wiki instead?
  • This is definitely worth pursuing - found a couple of issues with my game just by running with this very simple "blind idiot" version for about 30 mins.

    Plus it's strangely fascinating to watch ... :O)
  • Make that "four issues" ...

  • Created this unity package, which I'll update with new funtionality as it gets added:

  • Hey, great contribution! It'd definitely be great to have in the wikia (it'll be easier to find that way, in the forums things get buried over time). Posting it as a link would totally be fine I think. Cheers!
  • Suro : I have a very basic version simulating keyboard input running now - will polish a bit and put online, probably tomorrow.
  • Nice!
    I wonder what it will find :D
  • Got side-tracked into using the keyboard input simulation to automatically go through dialogue options + added some logic to have it try inventory item combinations and uses on hotspots - makes it progress through the game much faster.

    So, no keyboard-driven movement officially ready yet, I'm afraid - but soon!
  • Suro : I've now updated the package to support movement using arrow keys + a few other changes.

    Delete the folder "Automated Adventure Test System" if the previous version of the package was installed.

    Documentation is very limited at this point as this is still very much work in progress.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.