[{"data":1,"prerenderedAt":1361},["ShallowReactive",2],{"/hubnet-authoring":3,"/hubnet-authoring-surround":1351},{"id":4,"title":5,"body":6,"description":1316,"extension":1317,"meta":1318,"navigation":1336,"path":1347,"seo":1348,"stem":1349,"__hash__":1350},"content/hubnet-authoring.md","HubNet Authoring Guide",{"type":7,"value":8,"toc":1298},"minimark",[9,21,32,87,95,98,108,118,150,180,190,275,291,300,307,395,446,459,527,540,543,589,606,659,662,702,711,714,734,737,740,811,814,923,932,935,942,951,954,1003,1010,1017,1020,1023,1038,1058,1061,1068,1071,1169,1176,1179,1182,1229,1236,1266,1273,1280,1283,1295],[10,11,15],"h1",{"id":12,"className":13},"hubnet-authoring-guide",[14],"section-heading",[16,17,5],"a",{"className":18,"href":20},[19],"section-anchor","#hubnet-authoring-guide",[22,23,24,25,31],"p",{},"This guide shows how to understand and modify the code of existing HubNet\nactivities and write your own new ones. It assumes you are familiar with running\nHubNet activities, basic NetLogo code and NetLogo interface elements. For more\ngeneral information about HubNet see the ",[16,26,30],{"href":27,"rel":28},"https://docs.netlogo.org/hubnet",[29],"nofollow","HubNet Guide",".",[33,34,37,47],"div",{"className":35},[36],"toc",[38,39,42],"h4",{"id":40,"className":41},"table-of-contents",[14],[16,43,46],{"className":44,"href":45},[19],"#table-of-contents","Table of Contents",[48,49,50,57,63,69,75,81],"ul",{},[51,52,53],"li",{},[16,54,56],{"href":55},"#coding-hubnet-activities","Coding HubNet activities",[51,58,59],{},[16,60,62],{"href":61},"#how-to-make-a-client-interface","How to make a client interface",[51,64,65],{},[16,66,68],{"href":67},"#view-updates-on-the-clients","View updates on the clients",[51,70,71],{},[16,72,74],{"href":73},"#clicking-in-the-view-on-clients","Clicking in the view on clients",[51,76,77],{},[16,78,80],{"href":79},"#customizing-the-clients-view","Customizing the client’s view",[51,82,83],{},[16,84,86],{"href":85},"#plot-updates-on-the-clients","Plot updates on the clients",[88,89,92],"h2",{"id":90,"className":91},"coding-hubnet-activities",[14],[16,93,56],{"className":94,"href":55},[19],[22,96,97],{},"Many HubNet activities will share bits of the same code. That is the code that\nit used to setup the network and the code that is used to receive information\nfrom and send information to the clients. If you understand this code you should\nbe able to easily make modifications to existing activities and you should have\na good start on writing your own activities. To get you started we have provided\na Template model (in HubNet Activities -> Code Examples) that contains the most\nbasic components that will be in the majority of HubNet activities. You should\nbe able to use this activity as a starting point for most projects.",[99,100,101],"blockquote",{},[22,102,103,107],{},[104,105,106],"strong",{},"Code Example:"," Template",[109,110,113],"h3",{"id":111,"className":112},"setup",[14],[16,114,117],{"className":115,"href":116},[19],"#setup","Setup",[22,119,120,121,133,134,137,138,140,141,149],{},"To make a NetLogo model into a HubNet activity you must first initialize the\nnetwork. In most HubNet activities you will use the ",[122,123,125],"primitive",{"displayText":124,"permalink":124},"startup",[16,126,124],{"href":127,"rel":128,"className":130,"dataDisplayText":124,"target":132,"title":124},"/dictionary#startup",[129],"noopener",[131],"netlogo-wiki-link","_self"," procedure to\ninitialize the network. ",[135,136,124],"code",{}," is a special procedure that NetLogo runs\nautomatically when you open any model. That makes it a good place to put code\nthat you want to run once and only once (no matter how many times the user runs\nthe model). For HubNet we put the command that initializes the network in\n",[135,139,124],{}," because once the network is setup we don’t need to do so again. We\ninitialize the system using ",[122,142,144],{"displayText":143,"permalink":143},"hubnet-reset",[16,145,143],{"href":146,"rel":147,"className":148,"dataDisplayText":143,"target":132,"title":143},"/dictionary#hubnet-reset",[129],[131],", which will ask the user for a\nsession name and open up the HubNet Control Center. Here is the startup\nprocedure in the template model:",[151,152,153],"pre",{},[135,154,155,162,163,167,170,171,174],{},[156,157,161],"span",{"className":158},[159,160],"token","keyword","to"," ",[156,164,124],{"className":165},[159,166],"variable",[168,169],"br",{},"  ",[156,172,143],{"className":173},[159,166],[156,175,177,179],{"className":176},[159,160],[168,178],{},"end",[22,181,182,183,189],{},"Now that the network is all setup you don’t need to worry about calling\n",[122,184,185],{"displayText":143,"permalink":143},[16,186,143],{"href":146,"rel":187,"className":188,"dataDisplayText":143,"target":132,"title":143},[129],[131]," again. Take a look at the setup procedure in the template\nmodel:",[151,191,192],{},[135,193,194,162,197,200,170,202,207,170,209,213,170,215,219,170,221,162,225,230,232,233,235,236,162,240,162,244,249,235,251,162,255,162,259,162,264,267,269,270],{},[156,195,161],{"className":196},[159,160],[156,198,111],{"className":199},[159,166],[168,201],{},[156,203,206],{"className":204},[159,205],"command","cp",[168,208],{},[156,210,212],{"className":211},[159,205],"cd",[168,214],{},[156,216,218],{"className":217},[159,205],"clear-output",[168,220],{},[156,222,224],{"className":223},[159,205],"ask",[156,226,229],{"className":227},[159,228],"reporter","turtles",[168,231],{},"  [",[168,234],{},"    ",[156,237,239],{"className":238},[159,205],"set",[156,241,243],{"className":242},[159,166],"step-size",[156,245,248],{"className":246},[159,247],"number","1",[168,250],{},[156,252,254],{"className":253},[159,166],"hubnet-send",[156,256,258],{"className":257},[159,166],"user-id",[156,260,263],{"className":261},[159,262],"string","\"step-size\"",[156,265,243],{"className":266},[159,166],[168,268],{},"  ]",[156,271,273,179],{"className":272},[159,160],[168,274],{},[22,276,277,278,286,287,290],{},"For the most part it looks like most other setup procedures, however, you should\nnotice that it does not call ",[122,279,281],{"displayText":280,"permalink":280},"clear-all",[16,282,280],{"href":283,"rel":284,"className":285,"dataDisplayText":280,"target":132,"title":280},"/dictionary#clear-all",[129],[131],". In this model, and in the great\nmajority of HubNet activities in the Models Library, we have a breed of turtles\nthat represent the currently logged in clients. In this case we’ve called this\nbreed ",[135,288,289],{},"students",". Whenever a client logs in we create a student and record any\ninformation we might need later about that client in a turtle variable. Since we\ndon’t want to require users to log out and log back in every time we setup the\nactivity we don’t want to kill all the turtles, instead, we want to set all the\nvariables back to initial values and notify the clients of any changes we make\n(more on that later).",[109,292,295],{"id":293,"className":294},"receiving-messages-from-clients",[14],[16,296,299],{"className":297,"href":298},[19],"#receiving-messages-from-clients","Receiving messages from clients",[22,301,302,303,306],{},"During the activity you will be transferring data between the HubNet clients and\nthe server. Most HubNet activities will call a procedure in the ",[135,304,305],{},"go"," loop that\nchecks for new messages from clients in this case it’s called listen clients:",[151,308,309],{},[135,310,311,162,314,318,170,320,324,325,329,330,232,332,235,334,338,235,340,162,344,348,350,351,329,355,357,358,360,361,162,364,368,370,371,329,375,370,377,162,381,329,385,387,388,269,390],{},[156,312,161],{"className":313},[159,160],[156,315,317],{"className":316},[159,166],"listen-clients",[168,319],{},[156,321,323],{"className":322},[159,205],"while"," [ ",[156,326,328],{"className":327},[159,228],"hubnet-message-waiting?"," ]",[168,331],{},[168,333],{},[156,335,337],{"className":336},[159,166],"hubnet-fetch-message",[168,339],{},[156,341,343],{"className":342},[159,205],"ifelse",[156,345,347],{"className":346},[159,228],"hubnet-enter-message?",[168,349],{},"    [ ",[156,352,354],{"className":353},[159,166],"create-new-student",[168,356],{},"    [",[168,359],{},"      ",[156,362,343],{"className":363},[159,205],[156,365,367],{"className":366},[159,228],"hubnet-exit-message?",[168,369],{},"      [ ",[156,372,374],{"className":373},[159,166],"remove-student",[168,376],{},[156,378,380],{"className":379},[159,166],"execute-command",[156,382,384],{"className":383},[159,228],"hubnet-message-tag",[168,386],{},"    ]",[168,389],{},[156,391,393,179],{"className":392},[159,160],[168,394],{},[22,396,397,398,405,406,414,415,422,423,431,432,438,439,445],{},"As long as there are messages in the queue this loop fetches each message one at\na time. ",[122,399,400],{"displayText":337,"permalink":337},[16,401,337],{"href":402,"rel":403,"className":404,"dataDisplayText":337,"target":132,"title":337},"/dictionary#hubnet-fetch-message",[129],[131]," makes the next message in the queue the current\nmessage and sets the reporters ",[122,407,409],{"displayText":408,"permalink":408},"hubnet-message-source",[16,410,408],{"href":411,"rel":412,"className":413,"dataDisplayText":408,"target":132,"title":408},"/dictionary#hubnet-message-source",[129],[131],", ",[122,416,417],{"displayText":384,"permalink":384},[16,418,384],{"href":419,"rel":420,"className":421,"dataDisplayText":384,"target":132,"title":384},"/dictionary#hubnet-message-tag",[129],[131],"\nand ",[122,424,426],{"displayText":425,"permalink":425},"hubnet-message",[16,427,425],{"href":428,"rel":429,"className":430,"dataDisplayText":425,"target":132,"title":425},"/dictionary#hubnet-message",[129],[131]," to the appropriate values. The clients send messages when\nthe users login and logout any time the user manipulates one of the interface\nelements, that is, pushes a button, moves a slider, clicks in the view, etc. We\nstep through each message and decide what action to take depending on the type\nof message (enter, exit, or other), the ",[122,433,434],{"displayText":384,"permalink":384},[16,435,384],{"href":419,"rel":436,"className":437,"dataDisplayText":384,"target":132,"title":384},[129],[131]," (the name of the\ninterface element), and the ",[122,440,441],{"displayText":408,"permalink":408},[16,442,408],{"href":411,"rel":443,"className":444,"dataDisplayText":408,"target":132,"title":408},[129],[131]," of the message (the name\nof the client the message came from).",[22,447,448,449,451,452,458],{},"On an enter message we create a turtle with a ",[135,450,258],{}," that matches the\n",[122,453,454],{"displayText":408,"permalink":408},[16,455,408],{"href":411,"rel":456,"className":457,"dataDisplayText":408,"target":132,"title":408},[129],[131]," which is the name that each user enters upon entering\nthe activity, it is guaranteed to be unique.",[151,460,461],{},[135,462,463,162,466,469,170,471,162,475,478,232,480,235,482,162,485,162,488,491,235,493,162,496,162,500,503,235,505,162,508,162,511,514,235,516,520,269,522],{},[156,464,161],{"className":465},[159,160],[156,467,354],{"className":468},[159,166],[168,470],{},[156,472,474],{"className":473},[159,166],"create-students",[156,476,248],{"className":477},[159,247],[168,479],{},[168,481],{},[156,483,239],{"className":484},[159,205],[156,486,258],{"className":487},[159,166],[156,489,408],{"className":490},[159,228],[168,492],{},[156,494,239],{"className":495},[159,205],[156,497,499],{"className":498},[159,228],"label",[156,501,258],{"className":502},[159,166],[168,504],{},[156,506,239],{"className":507},[159,205],[156,509,243],{"className":510},[159,166],[156,512,248],{"className":513},[159,247],[168,515],{},[156,517,519],{"className":518},[159,166],"send-info-to-clients",[168,521],{},[156,523,525,179],{"className":524},[159,160],[168,526],{},[22,528,529,530,539],{},"At this point we set any other client variables to default values and send them\nto the clients if appropriate. We declared a ",[122,531,534],{"displayText":532,"permalink":533},"students-own","turtles-own",[16,535,532],{"href":536,"rel":537,"className":538,"dataDisplayText":532,"target":132,"title":532},"/dictionary#turtles-own",[129],[131],"\nvariable for every interface element on the client that holds state, that is,\nanything that would be a global variable on the server, sliders, choosers,\nswitches and input boxes. It is important to make sure that these variables stay\nsynchronized with the values visible on the client.",[22,541,542],{},"When the clients logout they send an exit message to the server which gives you\na chance to clean up any information you have been storing about the client, in\nthis case we merely have to ask the appropriate turtle to die.",[151,544,545],{},[135,546,547,162,550,553,170,555,162,558,162,561,565,566,162,569,162,573,576,577,579,580,329,584],{},[156,548,161],{"className":549},[159,160],[156,551,374],{"className":552},[159,166],[168,554],{},[156,556,224],{"className":557},[159,205],[156,559,289],{"className":560},[159,166],[156,562,564],{"className":563},[159,228],"with"," [",[156,567,258],{"className":568},[159,166],[156,570,572],{"className":571},[159,228],"=",[156,574,408],{"className":575},[159,228],"]",[168,578],{},"  [ ",[156,581,583],{"className":582},[159,205],"die",[156,585,587,179],{"className":586},[159,160],[168,588],{},[22,590,591,592,598,599,605],{},"All other messages are interface elements identified by the\n",[122,593,594],{"displayText":384,"permalink":384},[16,595,384],{"href":419,"rel":596,"className":597,"dataDisplayText":384,"target":132,"title":384},[129],[131]," which is the name that appears in the client interface.\nEvery time an interface element changes a message is sent to the server. Unless\nyou store the state of the values currently displayed in the client interface\nwill not be accessible in other parts of the model. That’s why we’ve declared a\n",[122,600,601],{"displayText":532,"permalink":533},[16,602,532],{"href":536,"rel":603,"className":604,"dataDisplayText":532,"target":132,"title":532},[129],[131]," variable for every interface element that has a\nstate (sliders, switches, etc). When we receive the message from the client we\nset the turtle variable to the content of the message:",[151,607,608],{},[135,609,610,162,614,162,617,162,620,623,625,626,170,628,162,631,162,634,565,637,162,640,162,643,576,646,350,648,162,651,162,654,329,657,576],{},[156,611,613],{"className":612},[159,205],"if",[156,615,384],{"className":616},[159,228],[156,618,572],{"className":619},[159,228],[156,621,263],{"className":622},[159,262],[168,624],{},"[",[168,627],{},[156,629,224],{"className":630},[159,205],[156,632,289],{"className":633},[159,166],[156,635,564],{"className":636},[159,228],[156,638,258],{"className":639},[159,166],[156,641,572],{"className":642},[159,228],[156,644,408],{"className":645},[159,228],[168,647],{},[156,649,239],{"className":650},[159,205],[156,652,243],{"className":653},[159,166],[156,655,425],{"className":656},[159,228],[168,658],{},[22,660,661],{},"Since buttons don’t have any associated data there is generally no associated\nturtle variable, instead they indicate an action taken by the client, just as\nwith a regular button there is often procedure associated with each button that\nyou call whenever you receive a message indicating the button has been pressed.\nThough it is certainly not required, the procedure is often a turtle procedure,\nthat is, something that the student turtle associated with the message source\ncan execute:",[151,663,664],{},[135,665,666,162,669,162,672,162,675,679,681,682,162,685,162,689,693,170,695,162,699,329],{},[156,667,613],{"className":668},[159,205],[156,670,205],{"className":671},[159,166],[156,673,572],{"className":674},[159,228],[156,676,678],{"className":677},[159,262],"\"move left\"",[168,680],{},"[ ",[156,683,239],{"className":684},[159,205],[156,686,688],{"className":687},[159,228],"heading",[156,690,692],{"className":691},[159,247],"270",[168,694],{},[156,696,698],{"className":697},[159,205],"fd",[156,700,248],{"className":701},[159,247],[109,703,706],{"id":704,"className":705},"sending-messages-to-clients",[14],[16,707,710],{"className":708,"href":709},[19],"#sending-messages-to-clients","Sending messages to clients",[22,712,713],{},"As mentioned earlier you can also send values to any interface elements that\ndisplay information: monitors, sliders, switches, choosers, and input boxes\n(note that plots and the view are special cases that have their own sections).",[22,715,716,717,724,725,733],{},"There are two primitives that allow you to send information ",[122,718,719],{"displayText":254,"permalink":254},[16,720,254],{"href":721,"rel":722,"className":723,"dataDisplayText":254,"target":132,"title":254},"/dictionary#hubnet-send",[129],[131]," and\n",[122,726,728],{"displayText":727,"permalink":727},"hubnet-broadcast",[16,729,727],{"href":730,"rel":731,"className":732,"dataDisplayText":727,"target":132,"title":727},"/dictionary#hubnet-broadcast",[129],[131],". Broadcast sends the information to all the clients; send\nsends to one client, or a selected group.",[22,735,736],{},"As suggested earlier, nothing on the client updates automatically. If a value\nchanges on the server, it is your responsibility as the activity author to\nupdate monitors on the client.",[22,738,739],{},"For example, say you have a slider on the client called step-size and a monitor\ncalled Step Size (note that the names must be different) you might write\nupdating code like this:",[151,741,742],{},[135,743,744,162,747,162,750,162,753,756,625,758,170,760,162,763,162,767,324,770,162,773,162,776,329,779,232,781,235,783,162,786,162,789,792,235,794,162,797,162,800,162,804,807,269,809,576],{},[156,745,613],{"className":746},[159,205],[156,748,384],{"className":749},[159,228],[156,751,572],{"className":752},[159,228],[156,754,263],{"className":755},[159,262],[168,757],{},[168,759],{},[156,761,224],{"className":762},[159,205],[156,764,766],{"className":765},[159,166],"student",[156,768,564],{"className":769},[159,228],[156,771,258],{"className":772},[159,166],[156,774,572],{"className":775},[159,228],[156,777,408],{"className":778},[159,228],[168,780],{},[168,782],{},[156,784,239],{"className":785},[159,205],[156,787,243],{"className":788},[159,166],[156,790,425],{"className":791},[159,228],[168,793],{},[156,795,254],{"className":796},[159,166],[156,798,258],{"className":799},[159,166],[156,801,803],{"className":802},[159,262],"\"Step Size\"",[156,805,243],{"className":806},[159,166],[168,808],{},[168,810],{},[22,812,813],{},"You can send any type of data you want, numbers, strings, lists, lists of lists,\nlists of strings, however, if the data is not appropriate for the receiving\ninterface element (say, if you were to send a string to a slider) the message\nwill be ignored. Here are a few code examples for different types of data:",[33,815,818],{"className":816},[817],"table-container",[819,820,822,823,844],"table",{"border":821},"","\n  ",[824,825,822,826],"thead",{},[827,828,829,830,834,839],"tr",{},"\n    ",[831,832,833],"th",{},"data type\n    ",[831,835,836,838],{},[135,837,727],{}," example\n    ",[831,840,841,843],{},[135,842,254],{}," example\n  ",[845,846,822,847,863,878,893,908],"tbody",{},[827,848,829,849,853,858],{},[850,851,852],"td",{},"number\n    ",[850,854,855,829],{},[135,856,857],{},"hubnet-broadcast \"A\" 3.14",[850,859,860,822],{},[135,861,862],{},"hubnet-send \"jimmy\" \"A\" 3.14",[827,864,829,865,868,873],{},[850,866,867],{},"string\n    ",[850,869,870,829],{},[135,871,872],{},"hubnet-broadcast \"STR1\" \"HI THERE\"",[850,874,875,822],{},[135,876,877],{},"hubnet-send [\"12\" \"15\"] \"STR1\" \"HI THERE\"",[827,879,829,880,883,888],{},[850,881,882],{},"list of numbers\n    ",[850,884,885,829],{},[135,886,887],{},"hubnet-broadcast \"L2\" [1 2 3]",[850,889,890,822],{},[135,891,892],{},"hubnet-send hubnet-message-source \"L2\" [1 2 3]",[827,894,829,895,898,903],{},[850,896,897],{},"matrix of numbers\n    ",[850,899,900,829],{},[135,901,902],{},"hubnet-broadcast \"[A]\" [[1 2] [3 4]]",[850,904,905,822],{},[135,906,907],{},"hubnet-send \"susie\" \"[A]\" [[1 2] [3 4]]",[827,909,829,910,913,918],{},[850,911,912],{},"list of strings\n    ",[850,914,915,829],{},[135,916,917],{},"hubnet-broadcast \"user-names\" [[\"jimmy\" \"susie\"] [\"bob\" \"george\"]]",[850,919,920],{},[135,921,922],{},"hubnet-send \"teacher\" \"user-names\" [[\"jimmy\" \"susie\"] [\"bob\" \"george\"]]",[109,924,927],{"id":925,"className":926},"examples",[14],[16,928,931],{"className":929,"href":930},[19],"#examples","Examples",[22,933,934],{},"Study the models in the “HubNet Activities” section of the Models Library to see\nhow these primitives are used in practice in the Code tab. Disease is a good one\nto start with.",[88,936,939],{"id":937,"className":938},"how-to-make-a-client-interface",[14],[16,940,62],{"className":941,"href":61},[19],[22,943,944,945,31],{},"Open the HubNet Client Editor, found in the Tools Menu. Add any buttons,\nsliders, switches, monitors, plots, choosers, or notes that you want just as you\nwould in the interface tab. You’ll notice that the information you enter for\neach of the widgets is slightly different than in the Interface panel. Widgets\non the client don’t interact with the model in the same way. Instead of a direct\nlink to commands and reporters the widgets send messages back to the server and\nthe model then determines how those messages affect the model. All widgets on\nthe client have a tag which is a name that uniquely identifies the widget. When\nthe server receives a message from that widget the tag is found in\n",[122,946,947],{"displayText":384,"permalink":384},[16,948,384],{"href":419,"rel":949,"className":950,"dataDisplayText":384,"target":132,"title":384},[129],[131],[22,952,953],{},"For example, if you have a button called “move left”, a slider called\n“step-size”, a switch called “all-in-one-step?”, and a monitor called\n“Location:”, the tags for these interface elements will be as follows:",[33,955,957],{"className":956},[817],[819,958,822,959,969],{"border":821},[824,960,822,961],{},[827,962,829,963,966],{},[831,964,965],{},"interface element\n    ",[831,967,968],{},"tag\n  ",[845,970,822,971,979,987,995],{},[827,972,829,973,976],{},[850,974,975],{},"move left\n    ",[850,977,978],{},"move left\n  ",[827,980,829,981,984],{},[850,982,983],{},"step-size\n    ",[850,985,986],{},"step-size\n  ",[827,988,829,989,992],{},[850,990,991],{},"all-in-one-step?\n    ",[850,993,994],{},"all-in-one-step?\n  ",[827,996,829,997,1000],{},[850,998,999],{},"Location:\n    ",[850,1001,1002],{},"Location:\n",[22,1004,1005,1006,1009],{},"Note that you can only have ",[104,1007,1008],{},"one"," interface element with a specific name.\nHaving more than one interface element with the same tag in the client interface\nwill result in unpredictable behavior since it is not clear which element you\nintended to send the information to.",[88,1011,1014],{"id":1012,"className":1013},"view-updates-on-the-clients",[14],[16,1015,68],{"className":1016,"href":67},[19],[22,1018,1019],{},"View mirroring lets views of the world be displayed in clients as well on the\nserver. View mirroring is enabled using a checkbox in the HubNet Control Center.",[22,1021,1022],{},"When mirroring is enabled, client views update whenever the view on the server\ndoes. To avoid excessive network traffic, the view should not update more often\nthan necessary. Therefore we strongly recommend using tick-based updates, rather\nthan continuous updates. See the View Updates section of the Programming Guide\nfor an explanation of the two types of updates.",[22,1024,1025,1026,1029,1030,1033,1034,1037],{},"With tick-based updates, updates happen when a ",[135,1027,1028],{},"tick"," or ",[135,1031,1032],{},"display"," command runs.\nWe recommend using these commands only inside an ",[135,1035,1036],{},"every"," block, to limit the\nfrequency of view updates and thus also limit network traffic. For example:",[151,1039,1040],{},[135,1041,1042,162,1045,1049,625,1051,170,1053,1056,576],{},[156,1043,1036],{"className":1044},[159,205],[156,1046,1048],{"className":1047},[159,247],"0.1",[168,1050],{},[168,1052],{},[156,1054,1032],{"className":1055},[159,205],[168,1057],{},[22,1059,1060],{},"If there is no View in the clients or if the Mirror 2D View on Clients checkbox\nin the HubNet Control Center is not checked, then no view updates are sent to\nthe clients.",[88,1062,1065],{"id":1063,"className":1064},"clicking-in-the-view-on-clients",[14],[16,1066,74],{"className":1067,"href":73},[19],[22,1069,1070],{},"If the View is included in the client, two messages are sent to the server every\ntime the user clicks in the view. The first message, when the user presses the\nmouse button, has the tag “View”. The second message, sent when the user\nreleases the mouse button, has the tag “Mouse Up”. Both messages consist of a\ntwo item list of the x and y coordinates. For example, to turn any patch that\nwas clicked on by the client red, you would use the following NetLogo code:",[151,1072,1073],{},[135,1074,1075,162,1078,162,1081,162,1084,1088,625,1090,170,1092,162,1095,162,1099,324,1102,162,1106,1109,1110,162,1114,162,1118,162,1122,1125,1126,1130,1132,1133,162,1137,1109,1140,162,1143,162,1146,162,1149,1152,1153,579,1155,162,1158,162,1162,329,1167,576],{},[156,1076,613],{"className":1077},[159,205],[156,1079,384],{"className":1080},[159,228],[156,1082,572],{"className":1083},[159,228],[156,1085,1087],{"className":1086},[159,262],"\"View\"",[168,1089],{},[168,1091],{},[156,1093,224],{"className":1094},[159,205],[156,1096,1098],{"className":1097},[159,228],"patches",[156,1100,564],{"className":1101},[159,228],[156,1103,1105],{"className":1104},[159,228],"pxcor",[156,1107,572],{"className":1108},[159,228]," (",[156,1111,1113],{"className":1112},[159,228],"round",[156,1115,1117],{"className":1116},[159,228],"item",[156,1119,1121],{"className":1120},[159,247],"0",[156,1123,425],{"className":1124},[159,228],") ",[156,1127,1129],{"className":1128},[159,228],"and",[168,1131],{},"                     ",[156,1134,1136],{"className":1135},[159,228],"pycor",[156,1138,572],{"className":1139},[159,228],[156,1141,1113],{"className":1142},[159,228],[156,1144,1117],{"className":1145},[159,228],[156,1147,248],{"className":1148},[159,247],[156,1150,425],{"className":1151},[159,228],") ]",[168,1154],{},[156,1156,239],{"className":1157},[159,205],[156,1159,1161],{"className":1160},[159,228],"pcolor",[156,1163,1166],{"className":1164},[159,1165],"constant","red",[168,1168],{},[88,1170,1173],{"id":1171,"className":1172},"customizing-the-clients-view",[14],[16,1174,80],{"className":1175,"href":79},[19],[22,1177,1178],{},"When view mirroring is enabled, by default clients see the same view the\nactivity leader sees on the server. But you can change this so that each client\nsees something different, not just a literal “mirror”.",[22,1180,1181],{},"You can change what a client sees in two distinct ways. We call them “client\nperspectives” and “client overrides”.",[22,1183,1184,1185,1193,1194,1202,1203,1211,1212,1220,1221,31],{},"Changing a client’s perspective means making it “watch” or “follow” a particular\nagent, much like the ",[122,1186,1188],{"displayText":1187,"permalink":1187},"watch",[16,1189,1187],{"href":1190,"rel":1191,"className":1192,"dataDisplayText":1187,"target":132,"title":1187},"/dictionary#watch",[129],[131]," and ",[122,1195,1197],{"displayText":1196,"permalink":1196},"follow",[16,1198,1196],{"href":1199,"rel":1200,"className":1201,"dataDisplayText":1196,"target":132,"title":1196},"/dictionary#follow",[129],[131]," commands that work with ordinary\nNetLogo models. See the dictionary entries for ",[122,1204,1206],{"displayText":1205,"permalink":1205},"hubnet-send-watch",[16,1207,1205],{"href":1208,"rel":1209,"className":1210,"dataDisplayText":1205,"target":132,"title":1205},"/dictionary#hubnet-send-watch",[129],[131],",\n",[122,1213,1215],{"displayText":1214,"permalink":1214},"hubnet-send-follow",[16,1216,1214],{"href":1217,"rel":1218,"className":1219,"dataDisplayText":1214,"target":132,"title":1214},"/dictionary#hubnet-send-follow",[129],[131],", and ",[122,1222,1224],{"displayText":1223,"permalink":1223},"hubnet-reset-perspective",[16,1225,1223],{"href":1226,"rel":1227,"className":1228,"dataDisplayText":1223,"target":132,"title":1223},"/dictionary#hubnet-reset-perspective",[129],[131],[99,1230,1231],{},[22,1232,1233,1235],{},[104,1234,106],{}," Client Perspective Example",[22,1237,1238,1239,1242,1243,1211,1251,1220,1259,31],{},"Client overrides let you change the appearance of patches, turtles, and links in\nthe client views. You can override any of the variables affecting an agent’s\nappearance, including the ",[135,1240,1241],{},"hidden?"," variable causing a turtle or link to be\nvisible or invisible. See the dictionary entries for ",[122,1244,1246],{"displayText":1245,"permalink":1245},"hubnet-send-override",[16,1247,1245],{"href":1248,"rel":1249,"className":1250,"dataDisplayText":1245,"target":132,"title":1245},"/dictionary#hubnet-send-override",[129],[131],[122,1252,1254],{"displayText":1253,"permalink":1253},"hubnet-clear-override",[16,1255,1253],{"href":1256,"rel":1257,"className":1258,"dataDisplayText":1253,"target":132,"title":1253},"/dictionary#hubnet-clear-override",[129],[131],[122,1260,1262],{"displayText":1261,"permalink":1253},"hubnet-clear-overrides",[16,1263,1261],{"href":1256,"rel":1264,"className":1265,"dataDisplayText":1261,"target":132,"title":1261},[129],[131],[99,1267,1268],{},[22,1269,1270,1272],{},[104,1271,106],{}," Client Overrides Example",[88,1274,1277],{"id":1275,"className":1276},"plot-updates-on-the-clients",[14],[16,1278,86],{"className":1279,"href":85},[19],[22,1281,1282],{},"If plot mirroring is enabled (in the HubNet Control Center) and a plot in the\nNetLogo model changes and a plot with the exact same name exists on the clients,\na message with that change is sent to the clients causing the client’s plot to\nmake the same change. For example, let’s pretend there is a HubNet model that\nhas a plot called Milk Supply in NetLogo and the clients. Milk Supply is the\ncurrent plot in NetLogo and in the Command Center you type:",[151,1284,1285],{},[135,1286,1287,162,1291],{},[156,1288,1290],{"className":1289},[159,205],"plot",[156,1292,1294],{"className":1293},[159,247],"5",[22,1296,1297],{},"This will cause a message to be sent to all the clients telling them that they\nneed to plot a point with a y value of 5 in the next position of the plot.\nNotice, if you are doing a lot of plotting all at once, this can generate a lot\nof plotting messages to be sent to the clients.",{"title":821,"searchDepth":1299,"depth":1300,"links":1301},5,3,[1302,1304,1311,1312,1313,1314,1315],{"id":40,"depth":1303,"text":46},4,{"id":90,"depth":1305,"text":56,"children":1306},2,[1307,1308,1309,1310],{"id":111,"depth":1300,"text":117},{"id":293,"depth":1300,"text":299},{"id":704,"depth":1300,"text":710},{"id":925,"depth":1300,"text":931},{"id":937,"depth":1305,"text":62},{"id":1012,"depth":1305,"text":68},{"id":1063,"depth":1305,"text":74},{"id":1171,"depth":1305,"text":80},{"id":1275,"depth":1305,"text":86},"Guide to creating HubNet activities that allow multiple users to participate in NetLogo simulations using networked devices.","md",{"source":1319,"metadataOutputPath":1320,"projectConfig":1321,"language":1328,"inheritFrom":1337,"output":1336,"version":1322,"keywords":1338,"tags":1344,"icon":1345,"assetsRoot":1346},"autogen/hubnet-authoring.md","content/hubnet-authoring.metadata.yaml",{"version":1322,"projectRoot":31,"scanRoot":1323,"outputRoot":1324,"defaults":1325,"engine":1331,"partials":1332,"dedupeIdenticalDiskWrites":1336},"7.0.4","autogen","content",{"inheritFrom":1326,"language":1328,"output":1329,"extension":1317,"title":1330,"version":1322},[1327],0,"en",false,"NetLogo User Manual","handlebars",{"directoryPaths":1333,"extensions":1334},[31],[1335,1317],"mustache",true,[1327],[1339,1340,1341,1342,1343],"HubNet Authoring","HubNet","Multi-user","Participatory Simulations","NetLogo",[1340,1339,1341,1342],"i-lucide-network","/home/runner/work/Helio/Helio/apps/docs/autogen","/hubnet-authoring",{"title":5,"description":1316},"hubnet-authoring","xIqj4PoXcLdiamB3_H0mGELgowpgVfKb3YO0Jai2pPE",[1352,1356],{"title":1340,"path":1353,"stem":1354,"description":1355},"/hubnet","hubnet","HubNet is a technology that lets you use NetLogo to run participatory simulations in the classroom where multiple users can interact with the model.",{"title":1357,"path":1358,"stem":1359,"description":1360},"Info Tab Guide","/infotab","infotab","Guide to NetLogo's graphical user interface, including the Info Tab Markdown.",1777657789295]