') 100% no-repeat;background-color:#fff;box-shadow:0 .2rem .2rem .1rem hsla(0,0%,40%,.5);cursor:pointer;margin-bottom:1rem;padding-right:3.2rem}select:focus{border-color:#4c4355;box-shadow:0 0 .2rem .2rem rgba(76,76,76,.3),0 .2rem .2rem .1rem hsla(0,0%,40%,.5)!important}textarea{min-height:6.4rem}label,legend{color:#332c39;display:block;font-weight:600}fieldset{border-width:0;padding:0}input[type=checkbox],input[type=radio]{cursor:pointer;display:inline;margin-bottom:0}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:default}input[type=checkbox]+span,input[type=radio]+span{cursor:pointer;font-weight:400;width:100%}input[type=checkbox]:disabled+span,input[type=radio]:disabled+span,span.toggleLabel+input[type=checkbox]:disabled{color:#616161;cursor:default!important}.label-inline{color:#19161c;display:inline-block}.label-inline+input{display:inline-block;margin-left:1.2rem;margin-right:1.2rem;width:unset}label>input[type=checkbox]{align-content:center;align-items:center;display:inline-flex}@media (min-width:680px){input[type=checkbox]+span:before{height:1.4rem;width:1.4rem}}span input[type=checkbox]:disabled+{cursor:default!important}input[type=checkbox]{opacity:0;position:absolute}input[type=checkbox]+span{cursor:pointer;line-height:2.3rem;padding-left:2.8rem;position:relative}input[type=checkbox]:active+span:before{background-color:#ccc}input[type=checkbox]+span:before{background-color:#f5f4f2;border:.1rem solid #665972;border-radius:.1rem;bottom:.3rem;display:inline-block;height:1.7rem;left:0;margin-right:.8rem;vertical-align:text-top;width:1.7rem}input[type=checkbox]+span:after,input[type=checkbox]+span:before{content:"";position:absolute;transition:all .05s;user-select:none}input[type=checkbox]+span:after{bottom:1.1rem;box-shadow:.2rem 0 0 #f5f4f2,.4rem 0 0 #f5f4f2,.4rem -.6rem 0 #f5f4f2,.4rem -.8rem 0 #f5f4f2;height:.3rem;left:.2rem;transform:rotate(90deg) scale(0);transform-origin:5% 85%;width:.3rem}input[type=checkbox]:checked+span:after{background-color:#8c3e34;box-shadow:.2rem 0 0 #8c3e34,.4rem 0 0 #8c3e34,.4rem -.2rem 0 #8c3e34,.4rem -.4rem 0 #8c3e34,.4rem -.6rem 0 #8c3e34,.4rem -.8rem 0 #8c3e34;content:"";transform:rotate(45deg) scale(1)}input[type=checkbox]:indeterminate+span:after{background-color:#8c3e34;bottom:1.1rem;box-shadow:unset;height:1.2rem;left:.4rem;transform:rotate(90deg) scale(1);width:.3rem}input[type=checkbox]:focus+span:before{border-color:#4c4355;border-width:.2rem;box-shadow:0 0 .2rem .2rem rgba(76,76,76,.3)!important}input[type=checkbox]:disabled+span:before{background:#8c8c8c;border:.1rem solid #8c8c8c;box-shadow:none}input[type=checkbox]:disabled+span{cursor:default!important}input[type=checkbox]:disabled:checked+span:before{cursor:default}input[type=checkbox]:disabled:checked+span:after{background:#ccc;box-shadow:.2rem 0 0 #ccc,.4rem 0 0 #ccc,.4rem -.2rem 0 #ccc,.4rem -.4rem 0 #ccc,.4rem -.6rem 0 #ccc,.4rem -.8rem 0 #ccc;cursor:default}input[type=checkbox]:disabled:indeterminate+span:after{background-color:#ccc}input[type=checkbox].toggle-switch{opacity:0;position:absolute}input[type=checkbox].toggle-switch+span:after,input[type=checkbox].toggle-switch+span:before{box-shadow:none;margin:0 .8rem 0 0;transform:unset;vertical-align:unset}input[type=checkbox].toggle-switch+span{align-items:baseline;display:inline-flex;height:2.3rem;margin:0;padding-left:4.8rem;vertical-align:text-bottom}input[type=checkbox].toggle-switch+span:before{background:gray;border:none;border-radius:1.6rem;content:"";display:inline-block;height:1.6rem;width:3.2rem}input[type=checkbox].toggle-switch+span:after{background-color:#f5f4f2;border-radius:50%;bottom:.5rem;content:"";display:inline-block;height:1.2rem;left:.2rem;transition:left .14s cubic-bezier(.32,0,.67,0);width:1.2rem}input[type=checkbox].toggle-switch:active+span:before,input[type=checkbox].toggle-switch:focus+span:before{border-color:#998ca5;box-shadow:0 0 .2rem .2rem rgba(140,126,154,.6)!important}input[type=checkbox].toggle-switch:disabled+span:after{background:#ccc!important}input[type=checkbox].toggle-switch:disabled+span:before{background:#8c8c8c!important;box-shadow:none!important}input[type=checkbox].toggle-switch:checked+span:after,input[type=checkbox].toggle-switch:checked+span:before{box-shadow:none;transform:unset}input[type=checkbox].toggle-switch:checked+span:after{background-color:#f5f4f2;display:inline-block;left:1.7rem}input[type=checkbox].toggle-switch:checked+span:before{background:#b3675c!important}input[type=checkbox].toggle-switch:checked:disabled+span:after{background:#ccc}input[type=checkbox].toggle-switch:checked:disabled+span:before{background:#ababab!important}.toggleLabel{color:#19161c;position:relative;top:.2rem}.radio-inline,.toggleLabelAfter,.toggleLabelBefore{margin-right:.8rem}.radio-inline{display:inline-block;min-width:9.2rem}input[type=radio]:checked,input[type=radio]:not(:checked){left:-9999px;position:absolute}input[type=radio]:checked+span:before{background-color:#f5f4f2;border:.1rem solid #665972;border-radius:100%;content:"";height:1.6rem;left:0;position:absolute;top:.15rem;width:1.6rem}input[type=radio]:active+span:before{background-color:#ababab;border:none;box-shadow:none}input[type=radio]:focus:checked+span:before{border:.1rem solid #4c4355;box-shadow:0 0 .2rem .2rem rgba(76,67,85,.6)}input[type=radio]:checked+span,input[type=radio]:not(:checked)+span{cursor:pointer;display:inline-block;line-height:2.2rem;padding-left:2.4rem;position:relative}input[type=radio]:checked:disabled+span:before{border:.1rem solid #8c8c8c;cursor:default}input[type=radio]:not(:checked)+span:before{background-color:#f5f4f2;border:.1rem solid #665972;border-radius:100%;content:"";height:1.6rem;left:0;position:absolute;top:.15rem;width:1.6rem}input[type=radio]:not(:checked):active+span:before{background-color:#ababab;border:none;box-shadow:none}input[type=radio]:not(:checked):focus+span:before{border:.1rem solid #4c4355;box-shadow:0 0 .2rem .2rem rgba(76,67,85,.6)}input[type=radio]:not(:checked):disabled+span:before{background-color:#8c8c8c;border:none;cursor:default}input[type=radio]:checked+span:after,input[type=radio]:not(:checked)+span:after{background:#8c3e34;border-radius:100%;content:"";height:.6rem;left:.5rem;position:absolute;top:.65rem;transform:scale(1);transition:transform .14s;width:.6rem}input[type=radio]:not(:checked)+span:after{transform:scale(0);transition:transform .5s cubic-bezier(.33,1,.68,1)}input[type=radio]:checked:disabled+span:before{background:0 0}input[type=radio]:checked:disabled+span:after{background:#8c8c8c;cursor:default}input[type=radio]:disabled+span{color:#616161;cursor:default}input[type=radio]:checked+span:after{opacity:1;transform:scale(1)}input[type=range]{-webkit-appearance:none;background:0 0;margin-top:1.6rem;width:100%}input[type=range]:focus{background-color:initial;outline:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:#fff;border:.1rem solid #8a8a8a;border-radius:45%;box-shadow:0 .2rem .2rem .1rem hsla(0,0%,40%,.5);cursor:pointer;height:2rem;margin-top:-.8rem;outline:0;width:2rem}input[type=range]:focus::-webkit-slider-thumb{border:.1rem solid #4c2c6c;box-shadow:0 0 .2rem .2rem rgba(76,67,85,.6),0 .2rem .2rem .1rem hsla(0,0%,40%,.5)!important}input[type=range]:disabled::-webkit-slider-thumb{background-color:#8c8c8c;border:.1rem solid #ccc;box-shadow:none;cursor:default}input[type=range]::-moz-range-thumb{background:#fff;border:.1rem solid #8a8a8a;border-radius:45%;box-shadow:0 .2rem .2rem .1rem hsla(0,0%,40%,.5);cursor:pointer;height:2rem;margin-top:-.8rem;outline:0;width:2rem}input[type=range]:focus::-moz-range-thumb{border:.1rem solid #4c2c6c;box-shadow:0 0 .2rem .2rem rgba(76,67,85,.6),0 .2rem .2rem .1rem hsla(0,0%,40%,.5)!important}input[type=range]:disabled::-moz-range-thumb{background-color:#8c8c8c;border:.1rem solid #ccc;box-shadow:none;cursor:default}input[type=range]::-webkit-slider-runnable-track{background-color:#8a8a8a;border-radius:0;cursor:pointer;height:.6rem;outline:0;width:100%}input[type=range]:disabled::-webkit-slider-runnable-track{background-color:#ccc;border:.1rem solid #8c8c8c;cursor:default}input[type=range]::-moz-range-track{background-color:#8a8a8a;border-radius:0;cursor:pointer;height:.6rem;outline:0;width:100%}input[type=range]:disabled::-moz-range-track{background-color:#ccc;border:.1rem solid #8c8c8c;cursor:default}.container,.container-fw{margin:0 auto;padding:0 .8rem;position:relative;width:100%}.container-fw{max-width:100vw}.container{max-width:80rem}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.colGap1{column-gap:1.6rem}.row.colGap2{column-gap:3.2rem}.row.colGap3{column-gap:4.8rem}.row.colGap4{column-gap:6.4rem}.row.row-no-padding,.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;min-width:0;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width:680px){.container,.container-fw{padding:0 2.4rem}.row{flex-direction:row;margin-left:-1.2rem;width:calc(100% + 2.4rem)}.row .column{margin-bottom:inherit;padding:0 1.2rem}}dl,ol,ul{list-style:none;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{margin:.4rem 0 .8rem 3em}dl ul>li,ol ul>li,ul ul>li{list-style:circle outside}ol,ul{list-style:none;margin:.4rem 0 .8rem 3em;padding-left:0}ol ul>li{list-style:disc outside}ol{list-style:decimal outside}ul{list-style:disc outside}fieldset{padding:0!important}input[type=range]{padding-bottom:1.2rem}li{margin-bottom:.6rem}blockquote,dl,figure,ol,p,pre,ul{margin-bottom:1.2rem;margin-top:0}table{margin:2.4rem 0}@media (min-width:680px){li{margin-bottom:.4rem}}table{border-spacing:0;max-width:100%}thead{background-color:#ababab;color:#212121}td,th{border-bottom:.1rem solid #8a8a8a;line-height:1;padding:.8rem;text-align:left}td:first-child,th:first-child{padding-left:1.6rem}td:last-child,th:last-child{padding-right:1.6rem}th{border-bottom:0;font-weight:400}@media (min-width:680px){table{width:auto}}b,strong{font-weight:700}p{margin-top:0}h1,h2,h3,h4,h5,h6{color:#414141;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:600;letter-spacing:-.1rem;line-height:1.2;margin:0 0 2.4rem}h1{font-size:3.6rem;font-weight:600;margin:3.2rem 0}h2{font-size:2.8rem;letter-spacing:0;line-height:1.25;margin:2rem 0}h3{font-size:1.8rem;font-weight:800}h3,h4{color:#0a0a0a;line-height:1.3}h4{font-size:1.6rem;text-decoration:underline}img{max-width:100%}figure{margin:0}video{display:block;margin:0 0 2.4rem;max-width:100%;outline:0}.clearfix:after{clear:both;content:" ";display:table}.float-left{float:left}.float-right{float:right}.cur-ptr{cursor:pointer}.disp-ib{display:inline-block!important}.disp-none{display:none!important}@media (max-width:679px){.show-sm-desktop{display:none!important}}@media (max-width:1279px){.show-lg-desktop{display:none!important}}@media (min-width:0px){.hide-mobile{display:none!important}}@media (min-width:680px){.hide-sm-desktop,.show-mobile{display:none!important}}@media (min-width:1280px){.hide-lg-desktop{display:none!important}}.pos-abs{position:absolute}.pl0{padding-left:0}.pl1{padding-left:.8rem}.pl2{padding-left:1.6rem}.pr0{padding-right:0}.pr1{padding-right:.8rem}.pr2{padding-right:1.6rem}.pb0{padding-bottom:0}.pb1{padding-bottom:.8rem}.pt0{padding-top:0}.pt1{padding-top:.8rem}.pt2{padding-top:1.6rem}.p0{padding:0}.p1{padding:.8rem}.p2{padding:1rem}.ml0{margin-left:0}.ml1{margin-left:.8rem}.mr0{margin-right:0}.mr1{margin-right:.8rem}.mr2{margin-right:1.6rem}.mt0{margin-top:0}.mt1{margin-top:.8rem}.mt2{margin-top:1.6rem}.mt3{margin-top:2.4rem}.mb0{margin-bottom:0}.mb1{margin-bottom:.8rem!important}.mb2{margin-bottom:1.6rem}.mb3{margin-bottom:2.4rem!important}.m0{margin:0}.mw100{max-width:100%}.m1{margin:.8rem}.m-center{margin:0 auto}.gpu-scrl{transform:translateZ(0)}.text-center{text-align:center}.text-right{text-align:right}.no-wrap{white-space:nowrap}.fsLarge{font-size:3rem}.fw-400{font-weight:400}.fw-500{font-weight:500}.fw-600{font-weight:600}.colorBlackLt{color:#4c4355}.ptrEvNone{pointer-events:none}.rootNavContainer{display:flex;flex-direction:column;margin-bottom:1.6rem}#root-nav{background:#ccc;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1.3rem;padding:1.2rem .4rem}#root-nav a{color:#8c3e34}#root-nav a:hover{color:#3e31a2}#root-nav ol{list-style:none;margin:0;padding-left:2.4rem}#root-nav ol li{display:inline-block;margin:0 .6rem 0 0;text-transform:capitalize}#root-nav ol li:first-child{margin-left:-2.4rem;padding-right:3.2rem;text-transform:none}#root-nav ol li:first-child:after,#root-nav ol li:last-child:after{content:""}#root-nav ol li:after{content:" /"}@media (min-width:680px){#root-nav{font-size:1.4rem}#root-nav ol li:first-child{padding-right:4rem}}a{color:#3e31a2;cursor:pointer;text-decoration:underline}a:focus,a:hover{color:#19161c}a:visited{color:#8c3e34}a:visited:focus,a:visited:hover{color:#3e31a2}body,html{height:100%}body{background-color:#ccc}.div__noscript{background-color:#8d47b3;color:#d0dc71;font-size:2.2rem}#container,#fakeContainer{background-color:#ccc;height:auto}.bg-c64-ltgreen{background-color:#acea88}.bg-c64-ltyellow{background-color:#d0dc71}.bg-c64-grey1{background-color:#ccc}.bg-c64-grey2{background-color:#ababab}.bg-c64-grey3{background-color:#8a8a8a}.bg-c64-ltblue{background-color:#7abfc7}.bg-c64-ltred{background-color:#bb776d}.bg-c64-green{background-color:#68a941}.bg-c64-ltpurple{background-color:#7c70da}.bg-c64-ltbrown{background-color:#905f25}.bg-c64-magenta{background-color:#8d47b3}.bg-c64-dkred{background-color:#8c3e34}.bg-c64-dkbrown{background-color:#574200}.bg-c64-dkpurple{background-color:#3e31a2}.colour-c64-ltgreen{color:#acea88}.colour-c64-ltyellow{color:#d0dc71}.colour-c64-grey1{color:#ccc}.colour-c64-grey2{color:#ababab}.colour-c64-grey3{color:#8a8a8a}.colour-c64-grey4{color:gray}.colour-c64-grey5{color:#676767}.colour-c64-grey6{color:#545454}.colour-c64-ltblue{color:#7abfc7}.colour-c64-ltred{color:#bb776d}.colour-c64-green{color:#68a941}.colour-c64-ltpurple{color:#7c70da}.colour-c64-ltbrown{color:#905f25}.colour-c64-magenta{color:#8d47b3}.colour-c64-dkred{color:#8c3e34}.colour-c64-dkbrown{color:#574200}.colour-c64-dkpurple{color:#3e31a2}
28 March 2019
Gathering Items With A Task-based AI I made some more progress since the last prototype. Not a lot of show off because of engine work. Quick breakdown of what’s new.
Updated GUI to streamline repeat item interactions More HUD information, like items available for range combat Decoupled how limbs and equipment work together Added jewelry items like rings a passive effect system for passive equipment bonuses AI (task system, pathing, rumor system) Monster Task AI My favourite new feature is the monster AI system. It isn’t too advanced, yet. No behaviour trees, GOAP, or stuff like that. I’ve focused on basic behaviours like pathing to a location, picking up items, dropping items, and a decent state machine to execute them. I also made a first pass at a task tracking system. To test it all out I’m working on a scenario where monsters gather items from the 4th floor of the map and drop them off on the bottom floor.
Your browser does not support the video tag. There’s one more thing going on in the video that I didn’t mention: a rumor/knowledge system. When a monster picks up an item, it wants to share this information with other monsters. As it travels throughout the map, the system does a perimeter check around the monster and shares this knowledge with any monster in that perimeter by assigning them a PickupItem
task at the place where the item was found. The monster travels to this location, but will find the item is already picked up. With nothing else to do it searches for nearby items and creates PickupItem
tasks for them. Once they are picked up new rumors are created about those items.
With the rumor systems in place, only one monster (on the first floor) is assigned a PickupItem
task. The behaviour of the other monsters and the tasks they get assigned are all kickstarted by the rumor system.
Bugs And Future Improvements You may notice there are a few problems and bugs to work out. Sometimes a DropItem
task doesn’t get added after a PickupItem
task because a monster already has the maximum number of tasks (3) all of which are pickup tasks. That guy just ends up wandering around the 4th floor hoarding items. Other times, a monster doesn’t have anymore tasks after dropping off an item and ends up wandering around the bottom level. It then sees nearby items on the bottom floor and adds tasks to pick them up which I don’t really want.
I think the rumor system could be a lot more interesting. I use failed tasks to manage the lifetime of a rumor. IF a monster arrives at its destination and doesn’t find an item matching the one described in PickupItem
task then that task failed. When a PickupItem
task fails any active rumors sdfor that location are removed. It’s possible this could happen before a second person even hears about the rumor which doesn’t really make sense. How would the monster spreading rumors know to stop? There’s all kind of interesting ways to change this. Maybe a rumor can only be stopped by talking to the monster that spreads it. In that case the monster who failed their PickupItem
task could create a new task to find that monster and get them to stop with the bullshit ;).
Until that happens, rumors about gold on the 4th floor would continue to spread. A rumor might never stop spreading if all the monsters trying to squelch it get killed before reaching the original monster. It could even lead to some fun situations. The player could lead gold-lusting monster to a trap by laying a breadcrumb trail of gold. To counteract this, monsters that escape your death trap could spread rumors of a deadly trap.
I didn’t update the combat too much since the last demo. The biggest change I made was automatically raising the combat UI when you walk into an enemy. And some extra HUD text when firing a ranged weapon. As I’ve played with the combat more, I’m coming towards the conclusion that the menu system is a dead end. There’s keystroke-efficiency problems, but I think my biggest problem is that it’s too abstract/unreal. I think I need to go back and figure out some primary actions that can lead to accessing those specialized commands.
I don’t know what that looks like, but I’m pretty sure I want a dedicated attack button. Maybe a weapon hotkey that flips through equippables in your inventory to get the next available weapon. But, this wouldn’t work with ranged-type weapons since they have a quiver. I’ll think about it more when I get around to working on combat again.